diff --git a/linter-4.2/src/Utils.ts b/linter-4.2/src/Utils.ts index 2ca1cdc8aab8b5933f8c7d7947d2db5a4fc15d8d..cf929d500eec332e08d686aa35a5215255bd837a 100644 --- a/linter-4.2/src/Utils.ts +++ b/linter-4.2/src/Utils.ts @@ -1072,8 +1072,8 @@ export class TsUtils { return false; } - public isBuiltinType(type: ts.Type): boolean { - return !(type.flags & ts.TypeFlags.NonPrimitive); + public isIntrinsicObjectType(type: ts.Type): boolean { + return !!(type.flags & ts.TypeFlags.NonPrimitive); } public isDynamicType(type: ts.Type | undefined): boolean | undefined { @@ -1085,13 +1085,17 @@ export class TsUtils { // return 'false' if it is not an object of standard library type one. // In the case of standard library type we need to determine context. + // Check the non-nullable version of type to eliminate 'undefined' type + // from the union type elements. + type = type.getNonNullableType(); + if (type.isUnion()) { for (let compType of type.types) { if (this.isLibraryType(compType)) { return true; } - if (!this.isStdLibraryType(compType) && !this.isBuiltinType(compType)) { + if (!this.isStdLibraryType(compType) && !this.isIntrinsicObjectType(compType) && !this.isAnyType(compType)) { return false; } } @@ -1102,7 +1106,7 @@ export class TsUtils { return true; } - if (!this.isStdLibraryType(type) && !this.isBuiltinType(type)) { + if (!this.isStdLibraryType(type) && !this.isIntrinsicObjectType(type) && !this.isAnyType(type)) { return false; } diff --git a/linter-4.2/test/dynamic_lib.d.ts b/linter-4.2/test/dynamic_lib.d.ts index b5eecaeef7700f080fd00a57fb8f705ed00e95cc..669198041fa8ef6025ce4a37b5eee6dceeb4614d 100644 --- a/linter-4.2/test/dynamic_lib.d.ts +++ b/linter-4.2/test/dynamic_lib.d.ts @@ -11,3 +11,11 @@ export declare interface I2 { f2?: Array; f3?: any; } + +export declare interface I3 { + f1: object; + f2?: object; + f3: Array; +} + +export declare function bar(p: object, q?: object): void \ No newline at end of file diff --git a/linter-4.2/test/dynamic_object_literals.ts b/linter-4.2/test/dynamic_object_literals.ts index 88a429917e754aaa04dc339b7719cb253d5573cf..ab2613f9752d122835ea87379dbdb7f0fec249d5 100644 --- a/linter-4.2/test/dynamic_object_literals.ts +++ b/linter-4.2/test/dynamic_object_literals.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { I, foo, I2 } from "./dynamic_lib" +import { I, foo, I2, I3, bar } from "./dynamic_lib" function main(): void { let obj: I = { @@ -38,4 +38,13 @@ function main(): void { f2: [{c: 30}, {d: 40}], f3: {a: '11', b: 444, c: {f: {d: [1, 2]}}} } + + bar({f2: 'abc', f3: 30}) + bar([{b1: 1, b2: 2}, {b3: '3'}], {c: 4, d: 5}) + + let obj3: I3 = { + f1: {a: 10, b: 20}, + f2: {a: '11', b: 444, c: {f: {d: [1, 2]}}}, + f3: [{c: 30}, {d: 40}] + } } diff --git a/linter/src/utils/TsUtils.ts b/linter/src/utils/TsUtils.ts index 0ded4c9298c9ad1aec49ec56a3f25af52f589396..4cab1e859cdacfb0d9f66052dad32b0511cc862f 100644 --- a/linter/src/utils/TsUtils.ts +++ b/linter/src/utils/TsUtils.ts @@ -19,7 +19,7 @@ import { STANDARD_LIBRARIES } from './consts/StandardLibraries'; import { STATEMENT_KINDS } from './consts/StatementKinds'; import { TYPED_ARRAYS } from './consts/TypedArrays'; import { getScriptKind } from './functions/GetScriptKind'; -import { isBuiltinType } from './functions/IsBuiltinType'; +import { isIntrinsicObjectType } from './functions/isIntrinsicObjectType'; import { isStdLibraryType } from './functions/IsStdLibrary'; import { isStructDeclaration } from './functions/IsStruct'; @@ -876,13 +876,17 @@ export class TsUtils { // return 'false' if it is not an object of standard library type one. // In the case of standard library type we need to determine context. + // Check the non-nullable version of type to eliminate 'undefined' type + // from the union type elements. + type = type.getNonNullableType(); + if (type.isUnion()) { for (let compType of type.types) { if (this.isLibraryType(compType)) { return true; } - if (!isStdLibraryType(compType) && !isBuiltinType(compType)) { + if (!isStdLibraryType(compType) && !isIntrinsicObjectType(compType) && !this.isAnyType(compType)) { return false; } } @@ -893,7 +897,7 @@ export class TsUtils { return true; } - if (!isStdLibraryType(type) && !isBuiltinType(type)) { + if (!isStdLibraryType(type) && !isIntrinsicObjectType(type) && !this.isAnyType(type)) { return false; } diff --git a/linter/src/utils/functions/IsBuiltinType.ts b/linter/src/utils/functions/isIntrinsicObjectType.ts similarity index 84% rename from linter/src/utils/functions/IsBuiltinType.ts rename to linter/src/utils/functions/isIntrinsicObjectType.ts index fb046d5bc987f93f81f8c8662f4541542ed42c11..a7ea0430158860fa5908f64597e531c9df478d2c 100644 --- a/linter/src/utils/functions/IsBuiltinType.ts +++ b/linter/src/utils/functions/isIntrinsicObjectType.ts @@ -15,6 +15,6 @@ import * as ts from 'typescript'; -export function isBuiltinType(type: ts.Type): boolean { - return !(type.flags & ts.TypeFlags.NonPrimitive); +export function isIntrinsicObjectType(type: ts.Type): boolean { + return !!(type.flags & ts.TypeFlags.NonPrimitive); } diff --git a/linter/test/dynamic_lib.d.ts b/linter/test/dynamic_lib.d.ts index b5eecaeef7700f080fd00a57fb8f705ed00e95cc..669198041fa8ef6025ce4a37b5eee6dceeb4614d 100644 --- a/linter/test/dynamic_lib.d.ts +++ b/linter/test/dynamic_lib.d.ts @@ -11,3 +11,11 @@ export declare interface I2 { f2?: Array; f3?: any; } + +export declare interface I3 { + f1: object; + f2?: object; + f3: Array; +} + +export declare function bar(p: object, q?: object): void \ No newline at end of file diff --git a/linter/test/dynamic_object_literals.ts b/linter/test/dynamic_object_literals.ts index 88a429917e754aaa04dc339b7719cb253d5573cf..ab2613f9752d122835ea87379dbdb7f0fec249d5 100644 --- a/linter/test/dynamic_object_literals.ts +++ b/linter/test/dynamic_object_literals.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { I, foo, I2 } from "./dynamic_lib" +import { I, foo, I2, I3, bar } from "./dynamic_lib" function main(): void { let obj: I = { @@ -38,4 +38,13 @@ function main(): void { f2: [{c: 30}, {d: 40}], f3: {a: '11', b: 444, c: {f: {d: [1, 2]}}} } + + bar({f2: 'abc', f3: 30}) + bar([{b1: 1, b2: 2}, {b3: '3'}], {c: 4, d: 5}) + + let obj3: I3 = { + f1: {a: 10, b: 20}, + f2: {a: '11', b: 444, c: {f: {d: [1, 2]}}}, + f3: [{c: 30}, {d: 40}] + } }