From f050215470b4f9761703bc091ff9a0fd056be172 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Tue, 25 Apr 2023 10:51:46 +0200 Subject: [PATCH 1/6] Avoid deprioritization of inferences made from mapped types with primitive type parameter constraints --- src/compiler/checker.ts | 11 ++- ...rameterConstraintInferencePriority.symbols | 71 ++++++++++++++++++ ...ParameterConstraintInferencePriority.types | 72 +++++++++++++++++++ ...ypeParameterConstraintInferencePriority.ts | 30 ++++++++ 4 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 tests/baselines/reference/mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.symbols create mode 100644 tests/baselines/reference/mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.types create mode 100644 tests/cases/compiler/mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 81cb730122da7..b50085022addf 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25059,9 +25059,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { applyToReturnTypes(source, target, inferFromTypes); } + function hasPrimitiveMappedTypeParameterConstaint(mappedType: MappedType): boolean { + const constraint = mappedType.typeParameter && getConstraintOfTypeParameter(mappedType.typeParameter); + return !!(constraint && constraint.flags & TypeFlags.Primitive); + } + function inferFromIndexTypes(source: Type, target: Type) { // Inferences across mapped type index signatures are pretty much the same a inferences to homomorphic variables - const priority = (getObjectFlags(source) & getObjectFlags(target) & ObjectFlags.Mapped) ? InferencePriority.HomomorphicMappedType : 0; + const priority = (getObjectFlags(source) & getObjectFlags(target) & ObjectFlags.Mapped) && + !hasPrimitiveMappedTypeParameterConstaint(source as MappedType) && + !hasPrimitiveMappedTypeParameterConstaint(target as MappedType) ? + InferencePriority.HomomorphicMappedType : + InferencePriority.None; const indexInfos = getIndexInfosOfType(target); if (isObjectTypeWithInferableIndex(source)) { for (const targetInfo of indexInfos) { diff --git a/tests/baselines/reference/mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.symbols b/tests/baselines/reference/mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.symbols new file mode 100644 index 0000000000000..8dd107c654aaa --- /dev/null +++ b/tests/baselines/reference/mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.symbols @@ -0,0 +1,71 @@ +=== tests/cases/compiler/mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54000 + +function foo(record: Record, entity: T) {} +>foo : Symbol(foo, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 0, 0)) +>T : Symbol(T, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 2, 13)) +>record : Symbol(record, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 2, 16)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 2, 13)) +>entity : Symbol(entity, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 2, 42)) +>T : Symbol(T, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 2, 13)) + +type StringArrayRecord = Record; +>StringArrayRecord : Symbol(StringArrayRecord, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 2, 56)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + +function test() { +>test : Symbol(test, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 4, 50)) + + const working: Record = {}; +>working : Symbol(working, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 7, 7)) +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) + + foo(working, []); +>foo : Symbol(foo, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 0, 0)) +>working : Symbol(working, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 7, 7)) + + const working2: StringArrayRecord = {}; +>working2 : Symbol(working2, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 10, 7)) +>StringArrayRecord : Symbol(StringArrayRecord, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 2, 56)) + + foo(working2, []); +>foo : Symbol(foo, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 0, 0)) +>working2 : Symbol(working2, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 10, 7)) +} + +// showcase the same behavior with index signature + +function bar(record: { [k: string]: T }, entity: T) {} +>bar : Symbol(bar, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 12, 1)) +>T : Symbol(T, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 16, 13)) +>record : Symbol(record, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 16, 16)) +>k : Symbol(k, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 16, 27)) +>T : Symbol(T, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 16, 13)) +>entity : Symbol(entity, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 16, 43)) +>T : Symbol(T, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 16, 13)) + +type StringArrayIndexSignature = { [k: string]: string[] }; +>StringArrayIndexSignature : Symbol(StringArrayIndexSignature, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 16, 57)) +>k : Symbol(k, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 18, 36)) + +function test2() { +>test2 : Symbol(test2, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 18, 59)) + + const working: { [k: string]: string[] } = {}; +>working : Symbol(working, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 21, 7)) +>k : Symbol(k, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 21, 20)) + + bar(working, []); +>bar : Symbol(bar, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 12, 1)) +>working : Symbol(working, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 21, 7)) + + const working2: StringArrayIndexSignature = {}; +>working2 : Symbol(working2, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 24, 7)) +>StringArrayIndexSignature : Symbol(StringArrayIndexSignature, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 16, 57)) + + bar(working2, []); +>bar : Symbol(bar, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 12, 1)) +>working2 : Symbol(working2, Decl(mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts, 24, 7)) +} + diff --git a/tests/baselines/reference/mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.types b/tests/baselines/reference/mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.types new file mode 100644 index 0000000000000..9823a940c2972 --- /dev/null +++ b/tests/baselines/reference/mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.types @@ -0,0 +1,72 @@ +=== tests/cases/compiler/mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts === +// repro from https://github.com/microsoft/TypeScript/issues/54000 + +function foo(record: Record, entity: T) {} +>foo : (record: Record, entity: T) => void +>record : Record +>entity : T + +type StringArrayRecord = Record; +>StringArrayRecord : { [x: string]: string[]; } + +function test() { +>test : () => void + + const working: Record = {}; +>working : Record +>{} : {} + + foo(working, []); +>foo(working, []) : void +>foo : (record: Record, entity: T) => void +>working : Record +>[] : never[] + + const working2: StringArrayRecord = {}; +>working2 : StringArrayRecord +>{} : {} + + foo(working2, []); +>foo(working2, []) : void +>foo : (record: Record, entity: T) => void +>working2 : StringArrayRecord +>[] : never[] +} + +// showcase the same behavior with index signature + +function bar(record: { [k: string]: T }, entity: T) {} +>bar : (record: { [k: string]: T; }, entity: T) => void +>record : { [k: string]: T; } +>k : string +>entity : T + +type StringArrayIndexSignature = { [k: string]: string[] }; +>StringArrayIndexSignature : { [k: string]: string[]; } +>k : string + +function test2() { +>test2 : () => void + + const working: { [k: string]: string[] } = {}; +>working : { [k: string]: string[]; } +>k : string +>{} : {} + + bar(working, []); +>bar(working, []) : void +>bar : (record: { [k: string]: T; }, entity: T) => void +>working : { [k: string]: string[]; } +>[] : never[] + + const working2: StringArrayIndexSignature = {}; +>working2 : StringArrayIndexSignature +>{} : {} + + bar(working2, []); +>bar(working2, []) : void +>bar : (record: { [k: string]: T; }, entity: T) => void +>working2 : StringArrayIndexSignature +>[] : never[] +} + diff --git a/tests/cases/compiler/mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts b/tests/cases/compiler/mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts new file mode 100644 index 0000000000000..1a0726b982149 --- /dev/null +++ b/tests/cases/compiler/mappedTypeWithPrimitiveTypeParameterConstraintInferencePriority.ts @@ -0,0 +1,30 @@ +// @strict: true +// @noEmit: true + +// repro from https://github.com/microsoft/TypeScript/issues/54000 + +function foo(record: Record, entity: T) {} + +type StringArrayRecord = Record; + +function test() { + const working: Record = {}; + foo(working, []); + + const working2: StringArrayRecord = {}; + foo(working2, []); +} + +// showcase the same behavior with index signature + +function bar(record: { [k: string]: T }, entity: T) {} + +type StringArrayIndexSignature = { [k: string]: string[] }; + +function test2() { + const working: { [k: string]: string[] } = {}; + bar(working, []); + + const working2: StringArrayIndexSignature = {}; + bar(working2, []); +} From 46aa15cc56b63ca92444402e7e6afb4804ec46dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sun, 12 Nov 2023 23:35:03 +0100 Subject: [PATCH 2/6] Introduce `InferencePriority.EmptyLiteral` --- src/compiler/checker.ts | 14 ++++---------- src/compiler/types.ts | 7 ++++--- tests/baselines/reference/api/typescript.d.ts | 7 ++++--- ...TemplateStringsTypeArgumentInference.errors.txt | 6 +++++- ...aggedTemplateStringsTypeArgumentInference.types | 6 +++--- ...plateStringsTypeArgumentInferenceES6.errors.txt | 6 +++++- ...edTemplateStringsTypeArgumentInferenceES6.types | 6 +++--- ...gedTemplateStringsWithOverloadResolution3.types | 2 +- ...emplateStringsWithOverloadResolution3_ES6.types | 2 +- tests/baselines/reference/tupleTypes.types | 4 ++-- .../reference/typeArgumentInference.errors.txt | 6 +++++- .../reference/typeArgumentInference.types | 6 +++--- ...ArgumentInferenceConstructSignatures.errors.txt | 6 +++++- .../typeArgumentInferenceConstructSignatures.types | 6 +++--- ...typeArgumentInferenceWithConstraints.errors.txt | 6 +++++- .../typeArgumentInferenceWithConstraints.types | 6 +++--- tests/baselines/reference/unionOfClassCalls.types | 4 ++-- tests/baselines/reference/widenToAny1.errors.txt | 5 +++-- tests/baselines/reference/widenToAny1.types | 2 +- 19 files changed, 62 insertions(+), 45 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9d4d371d94908..3bc6faa3a9412 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25237,6 +25237,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (candidate === blockedStringType) { return; } + if (isEmptyLiteralType(candidate) || isEmptyArrayLiteralType(candidate)) { + priority |= InferencePriority.EmptyLiteral; + } if (inference.priority === undefined || priority < inference.priority) { inference.candidates = undefined; inference.contraCandidates = undefined; @@ -25836,18 +25839,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { applyToReturnTypes(source, target, inferFromTypes); } - function hasPrimitiveMappedTypeParameterConstaint(mappedType: MappedType): boolean { - const constraint = mappedType.typeParameter && getConstraintOfTypeParameter(mappedType.typeParameter); - return !!(constraint && constraint.flags & TypeFlags.Primitive); - } - function inferFromIndexTypes(source: Type, target: Type) { // Inferences across mapped type index signatures are pretty much the same a inferences to homomorphic variables - const priority = (getObjectFlags(source) & getObjectFlags(target) & ObjectFlags.Mapped) && - !hasPrimitiveMappedTypeParameterConstaint(source as MappedType) && - !hasPrimitiveMappedTypeParameterConstaint(target as MappedType) ? - InferencePriority.HomomorphicMappedType : - InferencePriority.None; + const priority = (getObjectFlags(source) & getObjectFlags(target) & ObjectFlags.Mapped) ? InferencePriority.HomomorphicMappedType : 0; const indexInfos = getIndexInfosOfType(target); if (isObjectTypeWithInferableIndex(source)) { for (const targetInfo of indexInfos) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 34a2835822302..9a86285c92bd0 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6819,9 +6819,10 @@ export const enum InferencePriority { ContravariantConditional = 1 << 6, // Conditional type in contravariant position ReturnType = 1 << 7, // Inference made from return type of generic function LiteralKeyof = 1 << 8, // Inference made from a string literal to a keyof T - NoConstraints = 1 << 9, // Don't infer from constraints of instantiable types - AlwaysStrict = 1 << 10, // Always use strict rules for contravariant inferences - MaxValue = 1 << 11, // Seed for inference priority tracking + EmptyLiteral = 1 << 9, // Inference made from an empty literal type + NoConstraints = 1 << 10, // Don't infer from constraints of instantiable types + AlwaysStrict = 1 << 11, // Always use strict rules for contravariant inferences + MaxValue = 1 << 12, // Seed for inference priority tracking PriorityImpliesCombination = ReturnType | MappedTypeConstraint | LiteralKeyof, // These priorities imply that the resulting type should be a combination of all candidates Circularity = -1, // Inference circularity (value less than all other priorities) diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index eddf759a20b84..26244349ae4e5 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -7362,9 +7362,10 @@ declare namespace ts { ContravariantConditional = 64, ReturnType = 128, LiteralKeyof = 256, - NoConstraints = 512, - AlwaysStrict = 1024, - MaxValue = 2048, + EmptyLiteral = 512, + NoConstraints = 1024, + AlwaysStrict = 2048, + MaxValue = 4096, PriorityImpliesCombination = 416, Circularity = -1, } diff --git a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.errors.txt b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.errors.txt index e0fb14df83eb9..9a3534a3bbf2f 100644 --- a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.errors.txt +++ b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.errors.txt @@ -1,9 +1,10 @@ taggedTemplateStringsTypeArgumentInference.ts(62,36): error TS2345: Argument of type '0' is not assignable to parameter of type '""'. taggedTemplateStringsTypeArgumentInference.ts(63,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9a' must be of type 'string', but here has type '{}'. taggedTemplateStringsTypeArgumentInference.ts(76,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' must be of type '{ x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }', but here has type '{}'. +taggedTemplateStringsTypeArgumentInference.ts(89,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. -==== taggedTemplateStringsTypeArgumentInference.ts (3 errors) ==== +==== taggedTemplateStringsTypeArgumentInference.ts (4 errors) ==== // Generic tag with one parameter function noParams(n: T) { } noParams ``; @@ -101,5 +102,8 @@ taggedTemplateStringsTypeArgumentInference.ts(76,5): error TS2403: Subsequent va // Generic tag with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = someGenerics9 `${ [] }${ null }${ undefined }`; var arr: any[]; + ~~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. +!!! related TS6203 taggedTemplateStringsTypeArgumentInference.ts:88:5: 'arr' was also declared here. \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.types b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.types index 642c604fd0ef0..fce4c9e38d611 100644 --- a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.types +++ b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.types @@ -380,14 +380,14 @@ var a: any; // Generic tag with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = someGenerics9 `${ [] }${ null }${ undefined }`; ->arr : any[] ->someGenerics9 `${ [] }${ null }${ undefined }` : any[] +>arr : any +>someGenerics9 `${ [] }${ null }${ undefined }` : any >someGenerics9 : (strs: TemplateStringsArray, a: T, b: T, c: T) => T >`${ [] }${ null }${ undefined }` : string >[] : undefined[] >undefined : undefined var arr: any[]; ->arr : any[] +>arr : any diff --git a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.errors.txt b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.errors.txt index 2669575ffed30..a80a818940c23 100644 --- a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.errors.txt +++ b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.errors.txt @@ -1,9 +1,10 @@ taggedTemplateStringsTypeArgumentInferenceES6.ts(62,36): error TS2345: Argument of type '0' is not assignable to parameter of type '""'. taggedTemplateStringsTypeArgumentInferenceES6.ts(63,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9a' must be of type 'string', but here has type '{}'. taggedTemplateStringsTypeArgumentInferenceES6.ts(76,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' must be of type '{ x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }', but here has type '{}'. +taggedTemplateStringsTypeArgumentInferenceES6.ts(89,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. -==== taggedTemplateStringsTypeArgumentInferenceES6.ts (3 errors) ==== +==== taggedTemplateStringsTypeArgumentInferenceES6.ts (4 errors) ==== // Generic tag with one parameter function noParams(n: T) { } noParams ``; @@ -101,5 +102,8 @@ taggedTemplateStringsTypeArgumentInferenceES6.ts(76,5): error TS2403: Subsequent // Generic tag with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = someGenerics9 `${ [] }${ null }${ undefined }`; var arr: any[]; + ~~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. +!!! related TS6203 taggedTemplateStringsTypeArgumentInferenceES6.ts:88:5: 'arr' was also declared here. \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.types b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.types index 0f6c1805b5ece..26fd44e24fd70 100644 --- a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.types +++ b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.types @@ -380,14 +380,14 @@ var a: any; // Generic tag with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = someGenerics9 `${ [] }${ null }${ undefined }`; ->arr : any[] ->someGenerics9 `${ [] }${ null }${ undefined }` : any[] +>arr : any +>someGenerics9 `${ [] }${ null }${ undefined }` : any >someGenerics9 : (strs: TemplateStringsArray, a: T, b: T, c: T) => T >`${ [] }${ null }${ undefined }` : string >[] : undefined[] >undefined : undefined var arr: any[]; ->arr : any[] +>arr : any diff --git a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3.types b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3.types index 188200780a6c0..aaea5587af258 100644 --- a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3.types +++ b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3.types @@ -47,7 +47,7 @@ function fn2() { return undefined; } var d1: Date = fn2 `${ 0 }${ undefined }`; // contextually typed >d1 : Date ->fn2 `${ 0 }${ undefined }` : any +>fn2 `${ 0 }${ undefined }` : Date >fn2 : { (strs: TemplateStringsArray, s: string, n: number): number; (strs: TemplateStringsArray, n: number, t: T): T; } >`${ 0 }${ undefined }` : string >0 : 0 diff --git a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3_ES6.types b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3_ES6.types index 1b3b285f28013..2552989c5e875 100644 --- a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3_ES6.types +++ b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3_ES6.types @@ -47,7 +47,7 @@ function fn2() { return undefined; } var d1: Date = fn2 `${ 0 }${ undefined }`; // contextually typed >d1 : Date ->fn2 `${ 0 }${ undefined }` : any +>fn2 `${ 0 }${ undefined }` : Date >fn2 : { (strs: TemplateStringsArray, s: string, n: number): number; (strs: TemplateStringsArray, n: number, t: T): T; } >`${ 0 }${ undefined }` : string >0 : 0 diff --git a/tests/baselines/reference/tupleTypes.types b/tests/baselines/reference/tupleTypes.types index 2bd00b53103c6..b108870f6f5e1 100644 --- a/tests/baselines/reference/tupleTypes.types +++ b/tests/baselines/reference/tupleTypes.types @@ -155,9 +155,9 @@ var tt2: number | string; >tt2 : undefined tt = tuple2(1, undefined); ->tt = tuple2(1, undefined) : [number, any] +>tt = tuple2(1, undefined) : [number, string] >tt : [number, string] ->tuple2(1, undefined) : [number, any] +>tuple2(1, undefined) : [number, string] >tuple2 : (item0: T0, item1: T1) => [T0, T1] >1 : 1 >undefined : undefined diff --git a/tests/baselines/reference/typeArgumentInference.errors.txt b/tests/baselines/reference/typeArgumentInference.errors.txt index fac6267357ee7..78d7312e31371 100644 --- a/tests/baselines/reference/typeArgumentInference.errors.txt +++ b/tests/baselines/reference/typeArgumentInference.errors.txt @@ -2,9 +2,10 @@ typeArgumentInference.ts(68,29): error TS2345: Argument of type '0' is not assig typeArgumentInference.ts(69,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9a' must be of type 'string', but here has type '{}'. typeArgumentInference.ts(83,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' must be of type '{ x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }', but here has type '{}'. typeArgumentInference.ts(84,74): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type 'A92'. +typeArgumentInference.ts(98,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. -==== typeArgumentInference.ts (4 errors) ==== +==== typeArgumentInference.ts (5 errors) ==== // Generic call with no parameters function noParams() { } noParams(); @@ -113,5 +114,8 @@ typeArgumentInference.ts(84,74): error TS2353: Object literal may only specify k // Generic call with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = someGenerics9([], null, undefined); var arr: any[]; + ~~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. +!!! related TS6203 typeArgumentInference.ts:97:5: 'arr' was also declared here. \ No newline at end of file diff --git a/tests/baselines/reference/typeArgumentInference.types b/tests/baselines/reference/typeArgumentInference.types index a0ef4bf0d8bb8..bc61926cf096a 100644 --- a/tests/baselines/reference/typeArgumentInference.types +++ b/tests/baselines/reference/typeArgumentInference.types @@ -436,13 +436,13 @@ var a: any; // Generic call with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = someGenerics9([], null, undefined); ->arr : any[] ->someGenerics9([], null, undefined) : any[] +>arr : any +>someGenerics9([], null, undefined) : any >someGenerics9 : (a: T, b: T, c: T) => T >[] : undefined[] >undefined : undefined var arr: any[]; ->arr : any[] +>arr : any diff --git a/tests/baselines/reference/typeArgumentInferenceConstructSignatures.errors.txt b/tests/baselines/reference/typeArgumentInferenceConstructSignatures.errors.txt index 98b9862c07c8f..41f4815bf2844 100644 --- a/tests/baselines/reference/typeArgumentInferenceConstructSignatures.errors.txt +++ b/tests/baselines/reference/typeArgumentInferenceConstructSignatures.errors.txt @@ -12,9 +12,10 @@ typeArgumentInferenceConstructSignatures.ts(106,33): error TS2345: Argument of t typeArgumentInferenceConstructSignatures.ts(107,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9a' must be of type 'string', but here has type '{}'. typeArgumentInferenceConstructSignatures.ts(121,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' must be of type '{ x: number; z: Window & typeof globalThis; y?: undefined; } | { x: number; y: string; z?: undefined; }', but here has type '{}'. typeArgumentInferenceConstructSignatures.ts(122,74): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type 'A92'. +typeArgumentInferenceConstructSignatures.ts(136,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. -==== typeArgumentInferenceConstructSignatures.ts (8 errors) ==== +==== typeArgumentInferenceConstructSignatures.ts (9 errors) ==== // Generic call with no parameters interface NoParams { new (); @@ -175,5 +176,8 @@ typeArgumentInferenceConstructSignatures.ts(122,74): error TS2353: Object litera // Generic call with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = new someGenerics9([], null, undefined); var arr: any[]; + ~~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. +!!! related TS6203 typeArgumentInferenceConstructSignatures.ts:135:5: 'arr' was also declared here. \ No newline at end of file diff --git a/tests/baselines/reference/typeArgumentInferenceConstructSignatures.types b/tests/baselines/reference/typeArgumentInferenceConstructSignatures.types index 2c6fed11357a1..73906995ab30d 100644 --- a/tests/baselines/reference/typeArgumentInferenceConstructSignatures.types +++ b/tests/baselines/reference/typeArgumentInferenceConstructSignatures.types @@ -502,13 +502,13 @@ var a: any; // Generic call with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = new someGenerics9([], null, undefined); ->arr : any[] ->new someGenerics9([], null, undefined) : any[] +>arr : any +>new someGenerics9([], null, undefined) : any >someGenerics9 : someGenerics9 >[] : undefined[] >undefined : undefined var arr: any[]; ->arr : any[] +>arr : any diff --git a/tests/baselines/reference/typeArgumentInferenceWithConstraints.errors.txt b/tests/baselines/reference/typeArgumentInferenceWithConstraints.errors.txt index a4780472b019a..2a167ad081657 100644 --- a/tests/baselines/reference/typeArgumentInferenceWithConstraints.errors.txt +++ b/tests/baselines/reference/typeArgumentInferenceWithConstraints.errors.txt @@ -20,9 +20,10 @@ typeArgumentInferenceWithConstraints.ts(73,29): error TS2345: Argument of type ' typeArgumentInferenceWithConstraints.ts(74,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9a' must be of type 'string', but here has type '{}'. typeArgumentInferenceWithConstraints.ts(88,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' must be of type '{ x: number; z: Window & typeof globalThis; y?: undefined; } | { x: number; y: string; z?: undefined; }', but here has type '{}'. typeArgumentInferenceWithConstraints.ts(89,70): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type 'A92'. +typeArgumentInferenceWithConstraints.ts(103,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. -==== typeArgumentInferenceWithConstraints.ts (15 errors) ==== +==== typeArgumentInferenceWithConstraints.ts (16 errors) ==== // Generic call with no parameters function noParams() { } noParams(); @@ -166,5 +167,8 @@ typeArgumentInferenceWithConstraints.ts(89,70): error TS2353: Object literal may // Generic call with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = someGenerics9([], null, undefined); var arr: any[]; + ~~~ +!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. +!!! related TS6203 typeArgumentInferenceWithConstraints.ts:102:5: 'arr' was also declared here. \ No newline at end of file diff --git a/tests/baselines/reference/typeArgumentInferenceWithConstraints.types b/tests/baselines/reference/typeArgumentInferenceWithConstraints.types index 9dc5c458e6ae3..de56dabda9e3b 100644 --- a/tests/baselines/reference/typeArgumentInferenceWithConstraints.types +++ b/tests/baselines/reference/typeArgumentInferenceWithConstraints.types @@ -475,13 +475,13 @@ var a: any; // Generic call with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = someGenerics9([], null, undefined); ->arr : any[] ->someGenerics9([], null, undefined) : any[] +>arr : any +>someGenerics9([], null, undefined) : any >someGenerics9 : (a: T, b: T, c: T) => T >[] : undefined[] >undefined : undefined var arr: any[]; ->arr : any[] +>arr : any diff --git a/tests/baselines/reference/unionOfClassCalls.types b/tests/baselines/reference/unionOfClassCalls.types index c31e22185f9c7..100854b37a1d0 100644 --- a/tests/baselines/reference/unionOfClassCalls.types +++ b/tests/baselines/reference/unionOfClassCalls.types @@ -66,7 +66,7 @@ arr.map((a: number | string, index: number) => { // This case still doesn't work because `reduce` has multiple overloads :( arr.reduce((acc: Array, a: number | string, index: number) => { ->arr.reduce((acc: Array, a: number | string, index: number) => { return []}, []) : never[] +>arr.reduce((acc: Array, a: number | string, index: number) => { return []}, []) : string[] >arr.reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } | { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; (callbackfn: (previousValue: U_1, currentValue: string, currentIndex: number, array: string[]) => U_1, initialValue: U_1): U_1; } >arr : number[] | string[] >reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } | { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; (callbackfn: (previousValue: U_1, currentValue: string, currentIndex: number, array: string[]) => U_1, initialValue: U_1): U_1; } @@ -154,7 +154,7 @@ arr2.map((a: string, index: number) => { }) arr2.reduce((acc: string[], a: string, index: number) => { ->arr2.reduce((acc: string[], a: string, index: number) => { return []}, []) : never[] +>arr2.reduce((acc: string[], a: string, index: number) => { return []}, []) : string[] >arr2.reduce : { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; } >arr2 : string[] >reduce : { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; } diff --git a/tests/baselines/reference/widenToAny1.errors.txt b/tests/baselines/reference/widenToAny1.errors.txt index 3ecfc91260a24..c4a44d813f1ff 100644 --- a/tests/baselines/reference/widenToAny1.errors.txt +++ b/tests/baselines/reference/widenToAny1.errors.txt @@ -1,4 +1,4 @@ -widenToAny1.ts(4,5): error TS2322: Type 'string' is not assignable to type 'number'. +widenToAny1.ts(4,39): error TS2322: Type 'string' is not assignable to type 'number'. ==== widenToAny1.ts (1 errors) ==== @@ -6,6 +6,7 @@ widenToAny1.ts(4,5): error TS2322: Type 'string' is not assignable to type 'numb return undefined; } var z1: number = foo1({ x: undefined, y: "def" }); // Best common type is any - ~~ + ~ !!! error TS2322: Type 'string' is not assignable to type 'number'. +!!! related TS6500 widenToAny1.ts:1:30: The expected type comes from property 'y' which is declared here on type '{ x: number; y: number; }' \ No newline at end of file diff --git a/tests/baselines/reference/widenToAny1.types b/tests/baselines/reference/widenToAny1.types index 892feb9260def..f0aadd404dc62 100644 --- a/tests/baselines/reference/widenToAny1.types +++ b/tests/baselines/reference/widenToAny1.types @@ -12,7 +12,7 @@ function foo1(f1: { x: T; y: T }): T { } var z1: number = foo1({ x: undefined, y: "def" }); // Best common type is any >z1 : number ->foo1({ x: undefined, y: "def" }) : string +>foo1({ x: undefined, y: "def" }) : number >foo1 : (f1: { x: T; y: T; }) => T >{ x: undefined, y: "def" } : { x: undefined; y: string; } >x : undefined From 7cb45d5669be56755f43520cc0d60aa777bbc1f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sun, 12 Nov 2023 23:41:01 +0100 Subject: [PATCH 3/6] Bump the `InferencePriority.EmptyLiteral` --- src/compiler/types.ts | 6 +++--- tests/baselines/reference/api/typescript.d.ts | 8 ++++---- .../taggedTemplateStringsWithOverloadResolution3.types | 2 +- ...taggedTemplateStringsWithOverloadResolution3_ES6.types | 2 +- tests/baselines/reference/tupleTypes.types | 4 ++-- tests/baselines/reference/widenToAny1.errors.txt | 5 ++--- tests/baselines/reference/widenToAny1.types | 2 +- 7 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 9a86285c92bd0..e4d78e854babe 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6817,9 +6817,9 @@ export const enum InferencePriority { PartialHomomorphicMappedType = 1 << 4, // Partial reverse inference for homomorphic mapped type MappedTypeConstraint = 1 << 5, // Reverse inference for mapped type ContravariantConditional = 1 << 6, // Conditional type in contravariant position - ReturnType = 1 << 7, // Inference made from return type of generic function - LiteralKeyof = 1 << 8, // Inference made from a string literal to a keyof T - EmptyLiteral = 1 << 9, // Inference made from an empty literal type + EmptyLiteral = 1 << 7, // Inference made from an empty literal type + ReturnType = 1 << 8, // Inference made from return type of generic function + LiteralKeyof = 1 << 9, // Inference made from a string literal to a keyof T NoConstraints = 1 << 10, // Don't infer from constraints of instantiable types AlwaysStrict = 1 << 11, // Always use strict rules for contravariant inferences MaxValue = 1 << 12, // Seed for inference priority tracking diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 26244349ae4e5..f2040a3843ec2 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -7360,13 +7360,13 @@ declare namespace ts { PartialHomomorphicMappedType = 16, MappedTypeConstraint = 32, ContravariantConditional = 64, - ReturnType = 128, - LiteralKeyof = 256, - EmptyLiteral = 512, + EmptyLiteral = 128, + ReturnType = 256, + LiteralKeyof = 512, NoConstraints = 1024, AlwaysStrict = 2048, MaxValue = 4096, - PriorityImpliesCombination = 416, + PriorityImpliesCombination = 800, Circularity = -1, } interface FileExtensionInfo { diff --git a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3.types b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3.types index aaea5587af258..188200780a6c0 100644 --- a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3.types +++ b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3.types @@ -47,7 +47,7 @@ function fn2() { return undefined; } var d1: Date = fn2 `${ 0 }${ undefined }`; // contextually typed >d1 : Date ->fn2 `${ 0 }${ undefined }` : Date +>fn2 `${ 0 }${ undefined }` : any >fn2 : { (strs: TemplateStringsArray, s: string, n: number): number; (strs: TemplateStringsArray, n: number, t: T): T; } >`${ 0 }${ undefined }` : string >0 : 0 diff --git a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3_ES6.types b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3_ES6.types index 2552989c5e875..1b3b285f28013 100644 --- a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3_ES6.types +++ b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution3_ES6.types @@ -47,7 +47,7 @@ function fn2() { return undefined; } var d1: Date = fn2 `${ 0 }${ undefined }`; // contextually typed >d1 : Date ->fn2 `${ 0 }${ undefined }` : Date +>fn2 `${ 0 }${ undefined }` : any >fn2 : { (strs: TemplateStringsArray, s: string, n: number): number; (strs: TemplateStringsArray, n: number, t: T): T; } >`${ 0 }${ undefined }` : string >0 : 0 diff --git a/tests/baselines/reference/tupleTypes.types b/tests/baselines/reference/tupleTypes.types index b108870f6f5e1..2bd00b53103c6 100644 --- a/tests/baselines/reference/tupleTypes.types +++ b/tests/baselines/reference/tupleTypes.types @@ -155,9 +155,9 @@ var tt2: number | string; >tt2 : undefined tt = tuple2(1, undefined); ->tt = tuple2(1, undefined) : [number, string] +>tt = tuple2(1, undefined) : [number, any] >tt : [number, string] ->tuple2(1, undefined) : [number, string] +>tuple2(1, undefined) : [number, any] >tuple2 : (item0: T0, item1: T1) => [T0, T1] >1 : 1 >undefined : undefined diff --git a/tests/baselines/reference/widenToAny1.errors.txt b/tests/baselines/reference/widenToAny1.errors.txt index c4a44d813f1ff..3ecfc91260a24 100644 --- a/tests/baselines/reference/widenToAny1.errors.txt +++ b/tests/baselines/reference/widenToAny1.errors.txt @@ -1,4 +1,4 @@ -widenToAny1.ts(4,39): error TS2322: Type 'string' is not assignable to type 'number'. +widenToAny1.ts(4,5): error TS2322: Type 'string' is not assignable to type 'number'. ==== widenToAny1.ts (1 errors) ==== @@ -6,7 +6,6 @@ widenToAny1.ts(4,39): error TS2322: Type 'string' is not assignable to type 'num return undefined; } var z1: number = foo1({ x: undefined, y: "def" }); // Best common type is any - ~ + ~~ !!! error TS2322: Type 'string' is not assignable to type 'number'. -!!! related TS6500 widenToAny1.ts:1:30: The expected type comes from property 'y' which is declared here on type '{ x: number; y: number; }' \ No newline at end of file diff --git a/tests/baselines/reference/widenToAny1.types b/tests/baselines/reference/widenToAny1.types index f0aadd404dc62..892feb9260def 100644 --- a/tests/baselines/reference/widenToAny1.types +++ b/tests/baselines/reference/widenToAny1.types @@ -12,7 +12,7 @@ function foo1(f1: { x: T; y: T }): T { } var z1: number = foo1({ x: undefined, y: "def" }); // Best common type is any >z1 : number ->foo1({ x: undefined, y: "def" }) : number +>foo1({ x: undefined, y: "def" }) : string >foo1 : (f1: { x: T; y: T; }) => T >{ x: undefined, y: "def" } : { x: undefined; y: string; } >x : undefined From 74b274da7857d357b6b20666808ec5a036bd9108 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sun, 12 Nov 2023 23:51:07 +0100 Subject: [PATCH 4/6] remove outdated comment --- .../baselines/reference/unionOfClassCalls.js | 2 - .../reference/unionOfClassCalls.symbols | 85 +++++++++---------- .../reference/unionOfClassCalls.types | 1 - tests/cases/compiler/unionOfClassCalls.ts | 1 - 4 files changed, 42 insertions(+), 47 deletions(-) diff --git a/tests/baselines/reference/unionOfClassCalls.js b/tests/baselines/reference/unionOfClassCalls.js index 3398d25f5be13..4085f6613a4c8 100644 --- a/tests/baselines/reference/unionOfClassCalls.js +++ b/tests/baselines/reference/unionOfClassCalls.js @@ -27,7 +27,6 @@ arr.map((a: number | string, index: number) => { return index }) -// This case still doesn't work because `reduce` has multiple overloads :( arr.reduce((acc: Array, a: number | string, index: number) => { return [] }, []) @@ -92,7 +91,6 @@ var arr2 = []; arr.map(function (a, index) { return index; }); -// This case still doesn't work because `reduce` has multiple overloads :( arr.reduce(function (acc, a, index) { return []; }, []); diff --git a/tests/baselines/reference/unionOfClassCalls.symbols b/tests/baselines/reference/unionOfClassCalls.symbols index 44bf8856cf042..ab080bf147d0d 100644 --- a/tests/baselines/reference/unionOfClassCalls.symbols +++ b/tests/baselines/reference/unionOfClassCalls.symbols @@ -67,15 +67,14 @@ arr.map((a: number | string, index: number) => { }) -// This case still doesn't work because `reduce` has multiple overloads :( arr.reduce((acc: Array, a: number | string, index: number) => { >arr.reduce : Symbol(Array.reduce, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more) >arr : Symbol(arr, Decl(unionOfClassCalls.ts, 18, 5)) >reduce : Symbol(Array.reduce, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --) ... and 1 more) ->acc : Symbol(acc, Decl(unionOfClassCalls.ts, 27, 12)) +>acc : Symbol(acc, Decl(unionOfClassCalls.ts, 26, 12)) >Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->a : Symbol(a, Decl(unionOfClassCalls.ts, 27, 31)) ->index : Symbol(index, Decl(unionOfClassCalls.ts, 27, 51)) +>a : Symbol(a, Decl(unionOfClassCalls.ts, 26, 31)) +>index : Symbol(index, Decl(unionOfClassCalls.ts, 26, 51)) return [] }, []) @@ -84,11 +83,11 @@ arr.forEach((a: number | string, index: number) => { >arr.forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >arr : Symbol(arr, Decl(unionOfClassCalls.ts, 18, 5)) >forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->a : Symbol(a, Decl(unionOfClassCalls.ts, 31, 13)) ->index : Symbol(index, Decl(unionOfClassCalls.ts, 31, 32)) +>a : Symbol(a, Decl(unionOfClassCalls.ts, 30, 13)) +>index : Symbol(index, Decl(unionOfClassCalls.ts, 30, 32)) return index ->index : Symbol(index, Decl(unionOfClassCalls.ts, 31, 32)) +>index : Symbol(index, Decl(unionOfClassCalls.ts, 30, 32)) }) @@ -96,11 +95,11 @@ arr1.map((a: number, index: number) => { >arr1.map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) >arr1 : Symbol(arr1, Decl(unionOfClassCalls.ts, 19, 5)) >map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) ->a : Symbol(a, Decl(unionOfClassCalls.ts, 35, 10)) ->index : Symbol(index, Decl(unionOfClassCalls.ts, 35, 20)) +>a : Symbol(a, Decl(unionOfClassCalls.ts, 34, 10)) +>index : Symbol(index, Decl(unionOfClassCalls.ts, 34, 20)) return index ->index : Symbol(index, Decl(unionOfClassCalls.ts, 35, 20)) +>index : Symbol(index, Decl(unionOfClassCalls.ts, 34, 20)) }) @@ -108,12 +107,12 @@ arr1.reduce((acc: number[], a: number, index: number) => { >arr1.reduce : Symbol(Array.reduce, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >arr1 : Symbol(arr1, Decl(unionOfClassCalls.ts, 19, 5)) >reduce : Symbol(Array.reduce, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->acc : Symbol(acc, Decl(unionOfClassCalls.ts, 39, 13)) ->a : Symbol(a, Decl(unionOfClassCalls.ts, 39, 27)) ->index : Symbol(index, Decl(unionOfClassCalls.ts, 39, 38)) +>acc : Symbol(acc, Decl(unionOfClassCalls.ts, 38, 13)) +>a : Symbol(a, Decl(unionOfClassCalls.ts, 38, 27)) +>index : Symbol(index, Decl(unionOfClassCalls.ts, 38, 38)) return [a] ->a : Symbol(a, Decl(unionOfClassCalls.ts, 39, 27)) +>a : Symbol(a, Decl(unionOfClassCalls.ts, 38, 27)) }, []) @@ -121,22 +120,22 @@ arr1.forEach((a: number, index: number) => { >arr1.forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) >arr1 : Symbol(arr1, Decl(unionOfClassCalls.ts, 19, 5)) >forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) ->a : Symbol(a, Decl(unionOfClassCalls.ts, 43, 14)) ->index : Symbol(index, Decl(unionOfClassCalls.ts, 43, 24)) +>a : Symbol(a, Decl(unionOfClassCalls.ts, 42, 14)) +>index : Symbol(index, Decl(unionOfClassCalls.ts, 42, 24)) return index ->index : Symbol(index, Decl(unionOfClassCalls.ts, 43, 24)) +>index : Symbol(index, Decl(unionOfClassCalls.ts, 42, 24)) }) arr2.map((a: string, index: number) => { >arr2.map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) >arr2 : Symbol(arr2, Decl(unionOfClassCalls.ts, 20, 5)) >map : Symbol(Array.map, Decl(lib.es5.d.ts, --, --)) ->a : Symbol(a, Decl(unionOfClassCalls.ts, 46, 10)) ->index : Symbol(index, Decl(unionOfClassCalls.ts, 46, 21)) +>a : Symbol(a, Decl(unionOfClassCalls.ts, 45, 10)) +>index : Symbol(index, Decl(unionOfClassCalls.ts, 45, 21)) return index ->index : Symbol(index, Decl(unionOfClassCalls.ts, 46, 21)) +>index : Symbol(index, Decl(unionOfClassCalls.ts, 45, 21)) }) @@ -144,9 +143,9 @@ arr2.reduce((acc: string[], a: string, index: number) => { >arr2.reduce : Symbol(Array.reduce, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >arr2 : Symbol(arr2, Decl(unionOfClassCalls.ts, 20, 5)) >reduce : Symbol(Array.reduce, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->acc : Symbol(acc, Decl(unionOfClassCalls.ts, 50, 13)) ->a : Symbol(a, Decl(unionOfClassCalls.ts, 50, 27)) ->index : Symbol(index, Decl(unionOfClassCalls.ts, 50, 38)) +>acc : Symbol(acc, Decl(unionOfClassCalls.ts, 49, 13)) +>a : Symbol(a, Decl(unionOfClassCalls.ts, 49, 27)) +>index : Symbol(index, Decl(unionOfClassCalls.ts, 49, 38)) return [] }, []) @@ -155,54 +154,54 @@ arr2.forEach((a: string, index: number) => { >arr2.forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) >arr2 : Symbol(arr2, Decl(unionOfClassCalls.ts, 20, 5)) >forEach : Symbol(Array.forEach, Decl(lib.es5.d.ts, --, --)) ->a : Symbol(a, Decl(unionOfClassCalls.ts, 54, 14)) ->index : Symbol(index, Decl(unionOfClassCalls.ts, 54, 24)) +>a : Symbol(a, Decl(unionOfClassCalls.ts, 53, 14)) +>index : Symbol(index, Decl(unionOfClassCalls.ts, 53, 24)) return index ->index : Symbol(index, Decl(unionOfClassCalls.ts, 54, 24)) +>index : Symbol(index, Decl(unionOfClassCalls.ts, 53, 24)) }) // from https://github.com/microsoft/TypeScript/issues/36307 declare class Foo { ->Foo : Symbol(Foo, Decl(unionOfClassCalls.ts, 56, 2)) +>Foo : Symbol(Foo, Decl(unionOfClassCalls.ts, 55, 2)) doThing(): Promise ->doThing : Symbol(Foo.doThing, Decl(unionOfClassCalls.ts, 60, 19)) +>doThing : Symbol(Foo.doThing, Decl(unionOfClassCalls.ts, 59, 19)) >Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --)) } declare class Bar extends Foo { ->Bar : Symbol(Bar, Decl(unionOfClassCalls.ts, 62, 1)) ->Foo : Symbol(Foo, Decl(unionOfClassCalls.ts, 56, 2)) +>Bar : Symbol(Bar, Decl(unionOfClassCalls.ts, 61, 1)) +>Foo : Symbol(Foo, Decl(unionOfClassCalls.ts, 55, 2)) bar: number; ->bar : Symbol(Bar.bar, Decl(unionOfClassCalls.ts, 64, 31)) +>bar : Symbol(Bar.bar, Decl(unionOfClassCalls.ts, 63, 31)) } declare class Baz extends Foo { ->Baz : Symbol(Baz, Decl(unionOfClassCalls.ts, 66, 1)) ->Foo : Symbol(Foo, Decl(unionOfClassCalls.ts, 56, 2)) +>Baz : Symbol(Baz, Decl(unionOfClassCalls.ts, 65, 1)) +>Foo : Symbol(Foo, Decl(unionOfClassCalls.ts, 55, 2)) baz: number; ->baz : Symbol(Baz.baz, Decl(unionOfClassCalls.ts, 67, 31)) +>baz : Symbol(Baz.baz, Decl(unionOfClassCalls.ts, 66, 31)) } declare var a: Bar | Baz; ->a : Symbol(a, Decl(unionOfClassCalls.ts, 71, 11)) ->Bar : Symbol(Bar, Decl(unionOfClassCalls.ts, 62, 1)) ->Baz : Symbol(Baz, Decl(unionOfClassCalls.ts, 66, 1)) +>a : Symbol(a, Decl(unionOfClassCalls.ts, 70, 11)) +>Bar : Symbol(Bar, Decl(unionOfClassCalls.ts, 61, 1)) +>Baz : Symbol(Baz, Decl(unionOfClassCalls.ts, 65, 1)) // note, you must annotate `result` for now a.doThing().then((result: Bar | Baz) => { >a.doThing().then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->a.doThing : Symbol(Foo.doThing, Decl(unionOfClassCalls.ts, 60, 19), Decl(unionOfClassCalls.ts, 60, 19)) ->a : Symbol(a, Decl(unionOfClassCalls.ts, 71, 11)) ->doThing : Symbol(Foo.doThing, Decl(unionOfClassCalls.ts, 60, 19), Decl(unionOfClassCalls.ts, 60, 19)) +>a.doThing : Symbol(Foo.doThing, Decl(unionOfClassCalls.ts, 59, 19), Decl(unionOfClassCalls.ts, 59, 19)) +>a : Symbol(a, Decl(unionOfClassCalls.ts, 70, 11)) +>doThing : Symbol(Foo.doThing, Decl(unionOfClassCalls.ts, 59, 19), Decl(unionOfClassCalls.ts, 59, 19)) >then : Symbol(Promise.then, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) ->result : Symbol(result, Decl(unionOfClassCalls.ts, 73, 18)) ->Bar : Symbol(Bar, Decl(unionOfClassCalls.ts, 62, 1)) ->Baz : Symbol(Baz, Decl(unionOfClassCalls.ts, 66, 1)) +>result : Symbol(result, Decl(unionOfClassCalls.ts, 72, 18)) +>Bar : Symbol(Bar, Decl(unionOfClassCalls.ts, 61, 1)) +>Baz : Symbol(Baz, Decl(unionOfClassCalls.ts, 65, 1)) // whatever }); diff --git a/tests/baselines/reference/unionOfClassCalls.types b/tests/baselines/reference/unionOfClassCalls.types index 100854b37a1d0..a1c349ad384ff 100644 --- a/tests/baselines/reference/unionOfClassCalls.types +++ b/tests/baselines/reference/unionOfClassCalls.types @@ -64,7 +64,6 @@ arr.map((a: number | string, index: number) => { }) -// This case still doesn't work because `reduce` has multiple overloads :( arr.reduce((acc: Array, a: number | string, index: number) => { >arr.reduce((acc: Array, a: number | string, index: number) => { return []}, []) : string[] >arr.reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } | { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; (callbackfn: (previousValue: U_1, currentValue: string, currentIndex: number, array: string[]) => U_1, initialValue: U_1): U_1; } diff --git a/tests/cases/compiler/unionOfClassCalls.ts b/tests/cases/compiler/unionOfClassCalls.ts index 509fbb4b46a6c..35aafce272b99 100644 --- a/tests/cases/compiler/unionOfClassCalls.ts +++ b/tests/cases/compiler/unionOfClassCalls.ts @@ -25,7 +25,6 @@ arr.map((a: number | string, index: number) => { return index }) -// This case still doesn't work because `reduce` has multiple overloads :( arr.reduce((acc: Array, a: number | string, index: number) => { return [] }, []) From b1d6a3438e6c7b8d446dcb41b15040b80fd48478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 13 Nov 2023 00:22:14 +0100 Subject: [PATCH 5/6] Only deprioritize to `InferencePriority.ImplicitNever` outside of `strictNullChecks` --- src/compiler/checker.ts | 6 ++++-- src/compiler/types.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- .../taggedTemplateStringsTypeArgumentInference.errors.txt | 6 +----- .../taggedTemplateStringsTypeArgumentInference.types | 6 +++--- ...taggedTemplateStringsTypeArgumentInferenceES6.errors.txt | 6 +----- .../taggedTemplateStringsTypeArgumentInferenceES6.types | 6 +++--- tests/baselines/reference/typeArgumentInference.errors.txt | 6 +----- tests/baselines/reference/typeArgumentInference.types | 6 +++--- .../typeArgumentInferenceConstructSignatures.errors.txt | 6 +----- .../typeArgumentInferenceConstructSignatures.types | 6 +++--- .../typeArgumentInferenceWithConstraints.errors.txt | 6 +----- .../reference/typeArgumentInferenceWithConstraints.types | 6 +++--- 13 files changed, 26 insertions(+), 44 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3bc6faa3a9412..98d8851ded028 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25237,8 +25237,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (candidate === blockedStringType) { return; } - if (isEmptyLiteralType(candidate) || isEmptyArrayLiteralType(candidate)) { - priority |= InferencePriority.EmptyLiteral; + // without strictNullChecks an inference from an array of undefinedWideningType is still better than an inference from a widening null/undefined + // so we avoid deprioritization of those inferences when strictNullChecks are not enabled + if (strictNullChecks && (isEmptyLiteralType(candidate) || isEmptyArrayLiteralType(candidate))) { + priority |= InferencePriority.ImplicitNever; } if (inference.priority === undefined || priority < inference.priority) { inference.candidates = undefined; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index e4d78e854babe..8e3411333ac30 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6817,7 +6817,7 @@ export const enum InferencePriority { PartialHomomorphicMappedType = 1 << 4, // Partial reverse inference for homomorphic mapped type MappedTypeConstraint = 1 << 5, // Reverse inference for mapped type ContravariantConditional = 1 << 6, // Conditional type in contravariant position - EmptyLiteral = 1 << 7, // Inference made from an empty literal type + ImplicitNever = 1 << 7, // Inference made from an implicit never type ReturnType = 1 << 8, // Inference made from return type of generic function LiteralKeyof = 1 << 9, // Inference made from a string literal to a keyof T NoConstraints = 1 << 10, // Don't infer from constraints of instantiable types diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index f2040a3843ec2..bb395eb8f73ac 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -7360,7 +7360,7 @@ declare namespace ts { PartialHomomorphicMappedType = 16, MappedTypeConstraint = 32, ContravariantConditional = 64, - EmptyLiteral = 128, + ImplicitNever = 128, ReturnType = 256, LiteralKeyof = 512, NoConstraints = 1024, diff --git a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.errors.txt b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.errors.txt index 9a3534a3bbf2f..e0fb14df83eb9 100644 --- a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.errors.txt +++ b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.errors.txt @@ -1,10 +1,9 @@ taggedTemplateStringsTypeArgumentInference.ts(62,36): error TS2345: Argument of type '0' is not assignable to parameter of type '""'. taggedTemplateStringsTypeArgumentInference.ts(63,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9a' must be of type 'string', but here has type '{}'. taggedTemplateStringsTypeArgumentInference.ts(76,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' must be of type '{ x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }', but here has type '{}'. -taggedTemplateStringsTypeArgumentInference.ts(89,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. -==== taggedTemplateStringsTypeArgumentInference.ts (4 errors) ==== +==== taggedTemplateStringsTypeArgumentInference.ts (3 errors) ==== // Generic tag with one parameter function noParams(n: T) { } noParams ``; @@ -102,8 +101,5 @@ taggedTemplateStringsTypeArgumentInference.ts(89,5): error TS2403: Subsequent va // Generic tag with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = someGenerics9 `${ [] }${ null }${ undefined }`; var arr: any[]; - ~~~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. -!!! related TS6203 taggedTemplateStringsTypeArgumentInference.ts:88:5: 'arr' was also declared here. \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.types b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.types index fce4c9e38d611..642c604fd0ef0 100644 --- a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.types +++ b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInference.types @@ -380,14 +380,14 @@ var a: any; // Generic tag with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = someGenerics9 `${ [] }${ null }${ undefined }`; ->arr : any ->someGenerics9 `${ [] }${ null }${ undefined }` : any +>arr : any[] +>someGenerics9 `${ [] }${ null }${ undefined }` : any[] >someGenerics9 : (strs: TemplateStringsArray, a: T, b: T, c: T) => T >`${ [] }${ null }${ undefined }` : string >[] : undefined[] >undefined : undefined var arr: any[]; ->arr : any +>arr : any[] diff --git a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.errors.txt b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.errors.txt index a80a818940c23..2669575ffed30 100644 --- a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.errors.txt +++ b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.errors.txt @@ -1,10 +1,9 @@ taggedTemplateStringsTypeArgumentInferenceES6.ts(62,36): error TS2345: Argument of type '0' is not assignable to parameter of type '""'. taggedTemplateStringsTypeArgumentInferenceES6.ts(63,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9a' must be of type 'string', but here has type '{}'. taggedTemplateStringsTypeArgumentInferenceES6.ts(76,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' must be of type '{ x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }', but here has type '{}'. -taggedTemplateStringsTypeArgumentInferenceES6.ts(89,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. -==== taggedTemplateStringsTypeArgumentInferenceES6.ts (4 errors) ==== +==== taggedTemplateStringsTypeArgumentInferenceES6.ts (3 errors) ==== // Generic tag with one parameter function noParams(n: T) { } noParams ``; @@ -102,8 +101,5 @@ taggedTemplateStringsTypeArgumentInferenceES6.ts(89,5): error TS2403: Subsequent // Generic tag with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = someGenerics9 `${ [] }${ null }${ undefined }`; var arr: any[]; - ~~~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. -!!! related TS6203 taggedTemplateStringsTypeArgumentInferenceES6.ts:88:5: 'arr' was also declared here. \ No newline at end of file diff --git a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.types b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.types index 26fd44e24fd70..0f6c1805b5ece 100644 --- a/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.types +++ b/tests/baselines/reference/taggedTemplateStringsTypeArgumentInferenceES6.types @@ -380,14 +380,14 @@ var a: any; // Generic tag with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = someGenerics9 `${ [] }${ null }${ undefined }`; ->arr : any ->someGenerics9 `${ [] }${ null }${ undefined }` : any +>arr : any[] +>someGenerics9 `${ [] }${ null }${ undefined }` : any[] >someGenerics9 : (strs: TemplateStringsArray, a: T, b: T, c: T) => T >`${ [] }${ null }${ undefined }` : string >[] : undefined[] >undefined : undefined var arr: any[]; ->arr : any +>arr : any[] diff --git a/tests/baselines/reference/typeArgumentInference.errors.txt b/tests/baselines/reference/typeArgumentInference.errors.txt index 78d7312e31371..fac6267357ee7 100644 --- a/tests/baselines/reference/typeArgumentInference.errors.txt +++ b/tests/baselines/reference/typeArgumentInference.errors.txt @@ -2,10 +2,9 @@ typeArgumentInference.ts(68,29): error TS2345: Argument of type '0' is not assig typeArgumentInference.ts(69,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9a' must be of type 'string', but here has type '{}'. typeArgumentInference.ts(83,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' must be of type '{ x: number; z: Date; y?: undefined; } | { x: number; y: string; z?: undefined; }', but here has type '{}'. typeArgumentInference.ts(84,74): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type 'A92'. -typeArgumentInference.ts(98,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. -==== typeArgumentInference.ts (5 errors) ==== +==== typeArgumentInference.ts (4 errors) ==== // Generic call with no parameters function noParams() { } noParams(); @@ -114,8 +113,5 @@ typeArgumentInference.ts(98,5): error TS2403: Subsequent variable declarations m // Generic call with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = someGenerics9([], null, undefined); var arr: any[]; - ~~~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. -!!! related TS6203 typeArgumentInference.ts:97:5: 'arr' was also declared here. \ No newline at end of file diff --git a/tests/baselines/reference/typeArgumentInference.types b/tests/baselines/reference/typeArgumentInference.types index bc61926cf096a..a0ef4bf0d8bb8 100644 --- a/tests/baselines/reference/typeArgumentInference.types +++ b/tests/baselines/reference/typeArgumentInference.types @@ -436,13 +436,13 @@ var a: any; // Generic call with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = someGenerics9([], null, undefined); ->arr : any ->someGenerics9([], null, undefined) : any +>arr : any[] +>someGenerics9([], null, undefined) : any[] >someGenerics9 : (a: T, b: T, c: T) => T >[] : undefined[] >undefined : undefined var arr: any[]; ->arr : any +>arr : any[] diff --git a/tests/baselines/reference/typeArgumentInferenceConstructSignatures.errors.txt b/tests/baselines/reference/typeArgumentInferenceConstructSignatures.errors.txt index 41f4815bf2844..98b9862c07c8f 100644 --- a/tests/baselines/reference/typeArgumentInferenceConstructSignatures.errors.txt +++ b/tests/baselines/reference/typeArgumentInferenceConstructSignatures.errors.txt @@ -12,10 +12,9 @@ typeArgumentInferenceConstructSignatures.ts(106,33): error TS2345: Argument of t typeArgumentInferenceConstructSignatures.ts(107,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9a' must be of type 'string', but here has type '{}'. typeArgumentInferenceConstructSignatures.ts(121,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' must be of type '{ x: number; z: Window & typeof globalThis; y?: undefined; } | { x: number; y: string; z?: undefined; }', but here has type '{}'. typeArgumentInferenceConstructSignatures.ts(122,74): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type 'A92'. -typeArgumentInferenceConstructSignatures.ts(136,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. -==== typeArgumentInferenceConstructSignatures.ts (9 errors) ==== +==== typeArgumentInferenceConstructSignatures.ts (8 errors) ==== // Generic call with no parameters interface NoParams { new (); @@ -176,8 +175,5 @@ typeArgumentInferenceConstructSignatures.ts(136,5): error TS2403: Subsequent var // Generic call with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = new someGenerics9([], null, undefined); var arr: any[]; - ~~~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. -!!! related TS6203 typeArgumentInferenceConstructSignatures.ts:135:5: 'arr' was also declared here. \ No newline at end of file diff --git a/tests/baselines/reference/typeArgumentInferenceConstructSignatures.types b/tests/baselines/reference/typeArgumentInferenceConstructSignatures.types index 73906995ab30d..2c6fed11357a1 100644 --- a/tests/baselines/reference/typeArgumentInferenceConstructSignatures.types +++ b/tests/baselines/reference/typeArgumentInferenceConstructSignatures.types @@ -502,13 +502,13 @@ var a: any; // Generic call with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = new someGenerics9([], null, undefined); ->arr : any ->new someGenerics9([], null, undefined) : any +>arr : any[] +>new someGenerics9([], null, undefined) : any[] >someGenerics9 : someGenerics9 >[] : undefined[] >undefined : undefined var arr: any[]; ->arr : any +>arr : any[] diff --git a/tests/baselines/reference/typeArgumentInferenceWithConstraints.errors.txt b/tests/baselines/reference/typeArgumentInferenceWithConstraints.errors.txt index 2a167ad081657..a4780472b019a 100644 --- a/tests/baselines/reference/typeArgumentInferenceWithConstraints.errors.txt +++ b/tests/baselines/reference/typeArgumentInferenceWithConstraints.errors.txt @@ -20,10 +20,9 @@ typeArgumentInferenceWithConstraints.ts(73,29): error TS2345: Argument of type ' typeArgumentInferenceWithConstraints.ts(74,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9a' must be of type 'string', but here has type '{}'. typeArgumentInferenceWithConstraints.ts(88,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'a9e' must be of type '{ x: number; z: Window & typeof globalThis; y?: undefined; } | { x: number; y: string; z?: undefined; }', but here has type '{}'. typeArgumentInferenceWithConstraints.ts(89,70): error TS2353: Object literal may only specify known properties, and 'y' does not exist in type 'A92'. -typeArgumentInferenceWithConstraints.ts(103,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. -==== typeArgumentInferenceWithConstraints.ts (16 errors) ==== +==== typeArgumentInferenceWithConstraints.ts (15 errors) ==== // Generic call with no parameters function noParams() { } noParams(); @@ -167,8 +166,5 @@ typeArgumentInferenceWithConstraints.ts(103,5): error TS2403: Subsequent variabl // Generic call with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = someGenerics9([], null, undefined); var arr: any[]; - ~~~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'arr' must be of type 'any', but here has type 'any[]'. -!!! related TS6203 typeArgumentInferenceWithConstraints.ts:102:5: 'arr' was also declared here. \ No newline at end of file diff --git a/tests/baselines/reference/typeArgumentInferenceWithConstraints.types b/tests/baselines/reference/typeArgumentInferenceWithConstraints.types index de56dabda9e3b..9dc5c458e6ae3 100644 --- a/tests/baselines/reference/typeArgumentInferenceWithConstraints.types +++ b/tests/baselines/reference/typeArgumentInferenceWithConstraints.types @@ -475,13 +475,13 @@ var a: any; // Generic call with multiple parameters of generic type where one argument is [] and the other is not 'any' var arr = someGenerics9([], null, undefined); ->arr : any ->someGenerics9([], null, undefined) : any +>arr : any[] +>someGenerics9([], null, undefined) : any[] >someGenerics9 : (a: T, b: T, c: T) => T >[] : undefined[] >undefined : undefined var arr: any[]; ->arr : any +>arr : any[] From 1433a177f269af7e255ab5619e2b89b1470de922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Mon, 13 Nov 2023 00:30:11 +0100 Subject: [PATCH 6/6] simplify the check --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 98d8851ded028..fb42895d20e58 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25239,7 +25239,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } // without strictNullChecks an inference from an array of undefinedWideningType is still better than an inference from a widening null/undefined // so we avoid deprioritization of those inferences when strictNullChecks are not enabled - if (strictNullChecks && (isEmptyLiteralType(candidate) || isEmptyArrayLiteralType(candidate))) { + if (strictNullChecks && isEmptyArrayLiteralType(candidate)) { priority |= InferencePriority.ImplicitNever; } if (inference.priority === undefined || priority < inference.priority) {