From 934c78a89d2304d05a2e1a396dd508136cbd1851 Mon Sep 17 00:00:00 2001 From: Mohamed Hegazy Date: Thu, 19 May 2016 12:36:04 -0700 Subject: [PATCH] Fix #8694: check for singatures before calling a type empty --- src/compiler/checker.ts | 10 +++++++++- .../excessPropertyErrorForFunctionTypes.errors.txt | 12 ++++++++++++ .../reference/excessPropertyErrorForFunctionTypes.js | 8 ++++++++ .../compiler/excessPropertyErrorForFunctionTypes.ts | 4 ++++ 4 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/excessPropertyErrorForFunctionTypes.errors.txt create mode 100644 tests/baselines/reference/excessPropertyErrorForFunctionTypes.js create mode 100644 tests/cases/compiler/excessPropertyErrorForFunctionTypes.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 83dfdab423a..1f138f68d51 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6030,7 +6030,7 @@ namespace ts { if (type.flags & TypeFlags.ObjectType) { const resolved = resolveStructuredTypeMembers(type); if ((relation === assignableRelation || relation === comparableRelation) && - (type === globalObjectType || resolved.properties.length === 0) || + (type === globalObjectType || isEmptyObjectType(resolved)) || resolved.stringIndexInfo || resolved.numberIndexInfo || getPropertyOfType(type, name)) { return true; } @@ -6045,6 +6045,14 @@ namespace ts { return false; } + function isEmptyObjectType(t: ResolvedType) { + return t.properties.length === 0 && + t.callSignatures.length === 0 && + t.constructSignatures.length === 0 && + !t.stringIndexInfo && + !t.numberIndexInfo; + } + function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean { if (!(target.flags & TypeFlags.ObjectLiteralPatternWithComputedProperties) && maybeTypeOfKind(target, TypeFlags.ObjectType)) { for (const prop of getPropertiesOfObjectType(source)) { diff --git a/tests/baselines/reference/excessPropertyErrorForFunctionTypes.errors.txt b/tests/baselines/reference/excessPropertyErrorForFunctionTypes.errors.txt new file mode 100644 index 00000000000..dc9d6821e55 --- /dev/null +++ b/tests/baselines/reference/excessPropertyErrorForFunctionTypes.errors.txt @@ -0,0 +1,12 @@ +tests/cases/compiler/excessPropertyErrorForFunctionTypes.ts(4,44): error TS2322: Type '{ a: number; c: number; d: number; }' is not assignable to type '{ a: number; c: number; } | (() => any)'. + Object literal may only specify known properties, and 'd' does not exist in type '{ a: number; c: number; } | (() => any)'. + + +==== tests/cases/compiler/excessPropertyErrorForFunctionTypes.ts (1 errors) ==== + type FunctionType = () => any; + type DoesntWork = { a: number, c: number } | FunctionType; + + let doesntWork: DoesntWork = { a: 1, c: 2, d: 3 } + ~~~~ +!!! error TS2322: Type '{ a: number; c: number; d: number; }' is not assignable to type '{ a: number; c: number; } | (() => any)'. +!!! error TS2322: Object literal may only specify known properties, and 'd' does not exist in type '{ a: number; c: number; } | (() => any)'. \ No newline at end of file diff --git a/tests/baselines/reference/excessPropertyErrorForFunctionTypes.js b/tests/baselines/reference/excessPropertyErrorForFunctionTypes.js new file mode 100644 index 00000000000..d81608c79ba --- /dev/null +++ b/tests/baselines/reference/excessPropertyErrorForFunctionTypes.js @@ -0,0 +1,8 @@ +//// [excessPropertyErrorForFunctionTypes.ts] +type FunctionType = () => any; +type DoesntWork = { a: number, c: number } | FunctionType; + +let doesntWork: DoesntWork = { a: 1, c: 2, d: 3 } + +//// [excessPropertyErrorForFunctionTypes.js] +var doesntWork = { a: 1, c: 2, d: 3 }; diff --git a/tests/cases/compiler/excessPropertyErrorForFunctionTypes.ts b/tests/cases/compiler/excessPropertyErrorForFunctionTypes.ts new file mode 100644 index 00000000000..d86d6ddb77c --- /dev/null +++ b/tests/cases/compiler/excessPropertyErrorForFunctionTypes.ts @@ -0,0 +1,4 @@ +type FunctionType = () => any; +type DoesntWork = { a: number, c: number } | FunctionType; + +let doesntWork: DoesntWork = { a: 1, c: 2, d: 3 } \ No newline at end of file