mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
Merge pull request #22850 from Microsoft/tupleTypeInference
Only make inferences from tuple types of right arity
This commit is contained in:
commit
d7df84d641
@ -11603,6 +11603,13 @@ namespace ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function typesDefinitelyUnrelated(source: Type, target: Type) {
|
||||
// Two tuple types with different arity are definitely unrelated.
|
||||
// Two object types that each have a property that is unmatched in the other are definitely unrelated.
|
||||
return isTupleType(source) && isTupleType(target) && getTypeReferenceArity(<TypeReference>source) !== getTypeReferenceArity(<TypeReference>target) ||
|
||||
!!getUnmatchedProperty(source, target, /*requireOptionalProperties*/ false) && !!getUnmatchedProperty(target, source, /*requireOptionalProperties*/ false);
|
||||
}
|
||||
|
||||
function getTypeFromInference(inference: InferenceInfo) {
|
||||
return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) :
|
||||
inference.contraCandidates ? getIntersectionType(inference.contraCandidates) :
|
||||
@ -11873,9 +11880,8 @@ namespace ts {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Infer from the members of source and target only if the two types are possibly related. We check
|
||||
// in both directions because we may be inferring for a co-variant or a contra-variant position.
|
||||
if (!getUnmatchedProperty(source, target, /*requireOptionalProperties*/ false) || !getUnmatchedProperty(target, source, /*requireOptionalProperties*/ false)) {
|
||||
// Infer from the members of source and target only if the two types are possibly related
|
||||
if (!typesDefinitelyUnrelated(source, target)) {
|
||||
inferFromProperties(source, target);
|
||||
inferFromSignatures(source, target, SignatureKind.Call);
|
||||
inferFromSignatures(source, target, SignatureKind.Construct);
|
||||
|
||||
35
tests/baselines/reference/tupleTypeInference2.js
Normal file
35
tests/baselines/reference/tupleTypeInference2.js
Normal file
@ -0,0 +1,35 @@
|
||||
//// [tupleTypeInference2.ts]
|
||||
// Repro from #22564
|
||||
|
||||
type A<R> = [R] | [R, string];
|
||||
declare function f<T>(x: A<T>): T;
|
||||
f([undefined, ''] as [never, string]); // T: never
|
||||
f([undefined, ''] as [void, string]); // T: void
|
||||
|
||||
// Repro from #22563
|
||||
|
||||
type B<R, S> = [R] | [R, S];
|
||||
declare function g<T, U>(f: B<T, U>): U;
|
||||
g([[]] as [void[]]); // U: {}
|
||||
|
||||
type C<R, S> = [R[]] | [R[], S];
|
||||
declare function h<T, U>(f: C<T, U>): U;
|
||||
h([[]] as [void[]]); // U: {}
|
||||
|
||||
// Repro from #22562
|
||||
|
||||
type C2<R> = [R[]] | [R[], void];
|
||||
declare function h2<T>(f: C2<T>): T;
|
||||
h2([[]] as [never[]]); // T: never
|
||||
h2([[]] as [void[]]); // T: void
|
||||
|
||||
|
||||
//// [tupleTypeInference2.js]
|
||||
"use strict";
|
||||
// Repro from #22564
|
||||
f([undefined, '']); // T: never
|
||||
f([undefined, '']); // T: void
|
||||
g([[]]); // U: {}
|
||||
h([[]]); // U: {}
|
||||
h2([[]]); // T: never
|
||||
h2([[]]); // T: void
|
||||
91
tests/baselines/reference/tupleTypeInference2.symbols
Normal file
91
tests/baselines/reference/tupleTypeInference2.symbols
Normal file
@ -0,0 +1,91 @@
|
||||
=== tests/cases/compiler/tupleTypeInference2.ts ===
|
||||
// Repro from #22564
|
||||
|
||||
type A<R> = [R] | [R, string];
|
||||
>A : Symbol(A, Decl(tupleTypeInference2.ts, 0, 0))
|
||||
>R : Symbol(R, Decl(tupleTypeInference2.ts, 2, 7))
|
||||
>R : Symbol(R, Decl(tupleTypeInference2.ts, 2, 7))
|
||||
>R : Symbol(R, Decl(tupleTypeInference2.ts, 2, 7))
|
||||
|
||||
declare function f<T>(x: A<T>): T;
|
||||
>f : Symbol(f, Decl(tupleTypeInference2.ts, 2, 30))
|
||||
>T : Symbol(T, Decl(tupleTypeInference2.ts, 3, 19))
|
||||
>x : Symbol(x, Decl(tupleTypeInference2.ts, 3, 22))
|
||||
>A : Symbol(A, Decl(tupleTypeInference2.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(tupleTypeInference2.ts, 3, 19))
|
||||
>T : Symbol(T, Decl(tupleTypeInference2.ts, 3, 19))
|
||||
|
||||
f([undefined, ''] as [never, string]); // T: never
|
||||
>f : Symbol(f, Decl(tupleTypeInference2.ts, 2, 30))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
f([undefined, ''] as [void, string]); // T: void
|
||||
>f : Symbol(f, Decl(tupleTypeInference2.ts, 2, 30))
|
||||
>undefined : Symbol(undefined)
|
||||
|
||||
// Repro from #22563
|
||||
|
||||
type B<R, S> = [R] | [R, S];
|
||||
>B : Symbol(B, Decl(tupleTypeInference2.ts, 5, 37))
|
||||
>R : Symbol(R, Decl(tupleTypeInference2.ts, 9, 7))
|
||||
>S : Symbol(S, Decl(tupleTypeInference2.ts, 9, 9))
|
||||
>R : Symbol(R, Decl(tupleTypeInference2.ts, 9, 7))
|
||||
>R : Symbol(R, Decl(tupleTypeInference2.ts, 9, 7))
|
||||
>S : Symbol(S, Decl(tupleTypeInference2.ts, 9, 9))
|
||||
|
||||
declare function g<T, U>(f: B<T, U>): U;
|
||||
>g : Symbol(g, Decl(tupleTypeInference2.ts, 9, 28))
|
||||
>T : Symbol(T, Decl(tupleTypeInference2.ts, 10, 19))
|
||||
>U : Symbol(U, Decl(tupleTypeInference2.ts, 10, 21))
|
||||
>f : Symbol(f, Decl(tupleTypeInference2.ts, 10, 25))
|
||||
>B : Symbol(B, Decl(tupleTypeInference2.ts, 5, 37))
|
||||
>T : Symbol(T, Decl(tupleTypeInference2.ts, 10, 19))
|
||||
>U : Symbol(U, Decl(tupleTypeInference2.ts, 10, 21))
|
||||
>U : Symbol(U, Decl(tupleTypeInference2.ts, 10, 21))
|
||||
|
||||
g([[]] as [void[]]); // U: {}
|
||||
>g : Symbol(g, Decl(tupleTypeInference2.ts, 9, 28))
|
||||
|
||||
type C<R, S> = [R[]] | [R[], S];
|
||||
>C : Symbol(C, Decl(tupleTypeInference2.ts, 11, 20))
|
||||
>R : Symbol(R, Decl(tupleTypeInference2.ts, 13, 7))
|
||||
>S : Symbol(S, Decl(tupleTypeInference2.ts, 13, 9))
|
||||
>R : Symbol(R, Decl(tupleTypeInference2.ts, 13, 7))
|
||||
>R : Symbol(R, Decl(tupleTypeInference2.ts, 13, 7))
|
||||
>S : Symbol(S, Decl(tupleTypeInference2.ts, 13, 9))
|
||||
|
||||
declare function h<T, U>(f: C<T, U>): U;
|
||||
>h : Symbol(h, Decl(tupleTypeInference2.ts, 13, 32))
|
||||
>T : Symbol(T, Decl(tupleTypeInference2.ts, 14, 19))
|
||||
>U : Symbol(U, Decl(tupleTypeInference2.ts, 14, 21))
|
||||
>f : Symbol(f, Decl(tupleTypeInference2.ts, 14, 25))
|
||||
>C : Symbol(C, Decl(tupleTypeInference2.ts, 11, 20))
|
||||
>T : Symbol(T, Decl(tupleTypeInference2.ts, 14, 19))
|
||||
>U : Symbol(U, Decl(tupleTypeInference2.ts, 14, 21))
|
||||
>U : Symbol(U, Decl(tupleTypeInference2.ts, 14, 21))
|
||||
|
||||
h([[]] as [void[]]); // U: {}
|
||||
>h : Symbol(h, Decl(tupleTypeInference2.ts, 13, 32))
|
||||
|
||||
// Repro from #22562
|
||||
|
||||
type C2<R> = [R[]] | [R[], void];
|
||||
>C2 : Symbol(C2, Decl(tupleTypeInference2.ts, 15, 20))
|
||||
>R : Symbol(R, Decl(tupleTypeInference2.ts, 19, 8))
|
||||
>R : Symbol(R, Decl(tupleTypeInference2.ts, 19, 8))
|
||||
>R : Symbol(R, Decl(tupleTypeInference2.ts, 19, 8))
|
||||
|
||||
declare function h2<T>(f: C2<T>): T;
|
||||
>h2 : Symbol(h2, Decl(tupleTypeInference2.ts, 19, 33))
|
||||
>T : Symbol(T, Decl(tupleTypeInference2.ts, 20, 20))
|
||||
>f : Symbol(f, Decl(tupleTypeInference2.ts, 20, 23))
|
||||
>C2 : Symbol(C2, Decl(tupleTypeInference2.ts, 15, 20))
|
||||
>T : Symbol(T, Decl(tupleTypeInference2.ts, 20, 20))
|
||||
>T : Symbol(T, Decl(tupleTypeInference2.ts, 20, 20))
|
||||
|
||||
h2([[]] as [never[]]); // T: never
|
||||
>h2 : Symbol(h2, Decl(tupleTypeInference2.ts, 19, 33))
|
||||
|
||||
h2([[]] as [void[]]); // T: void
|
||||
>h2 : Symbol(h2, Decl(tupleTypeInference2.ts, 19, 33))
|
||||
|
||||
115
tests/baselines/reference/tupleTypeInference2.types
Normal file
115
tests/baselines/reference/tupleTypeInference2.types
Normal file
@ -0,0 +1,115 @@
|
||||
=== tests/cases/compiler/tupleTypeInference2.ts ===
|
||||
// Repro from #22564
|
||||
|
||||
type A<R> = [R] | [R, string];
|
||||
>A : A<R>
|
||||
>R : R
|
||||
>R : R
|
||||
>R : R
|
||||
|
||||
declare function f<T>(x: A<T>): T;
|
||||
>f : <T>(x: A<T>) => T
|
||||
>T : T
|
||||
>x : A<T>
|
||||
>A : A<R>
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
f([undefined, ''] as [never, string]); // T: never
|
||||
>f([undefined, ''] as [never, string]) : never
|
||||
>f : <T>(x: A<T>) => T
|
||||
>[undefined, ''] as [never, string] : [never, string]
|
||||
>[undefined, ''] : [undefined, string]
|
||||
>undefined : undefined
|
||||
>'' : ""
|
||||
|
||||
f([undefined, ''] as [void, string]); // T: void
|
||||
>f([undefined, ''] as [void, string]) : void
|
||||
>f : <T>(x: A<T>) => T
|
||||
>[undefined, ''] as [void, string] : [void, string]
|
||||
>[undefined, ''] : [undefined, string]
|
||||
>undefined : undefined
|
||||
>'' : ""
|
||||
|
||||
// Repro from #22563
|
||||
|
||||
type B<R, S> = [R] | [R, S];
|
||||
>B : B<R, S>
|
||||
>R : R
|
||||
>S : S
|
||||
>R : R
|
||||
>R : R
|
||||
>S : S
|
||||
|
||||
declare function g<T, U>(f: B<T, U>): U;
|
||||
>g : <T, U>(f: B<T, U>) => U
|
||||
>T : T
|
||||
>U : U
|
||||
>f : B<T, U>
|
||||
>B : B<R, S>
|
||||
>T : T
|
||||
>U : U
|
||||
>U : U
|
||||
|
||||
g([[]] as [void[]]); // U: {}
|
||||
>g([[]] as [void[]]) : {}
|
||||
>g : <T, U>(f: B<T, U>) => U
|
||||
>[[]] as [void[]] : [void[]]
|
||||
>[[]] : [never[]]
|
||||
>[] : never[]
|
||||
|
||||
type C<R, S> = [R[]] | [R[], S];
|
||||
>C : C<R, S>
|
||||
>R : R
|
||||
>S : S
|
||||
>R : R
|
||||
>R : R
|
||||
>S : S
|
||||
|
||||
declare function h<T, U>(f: C<T, U>): U;
|
||||
>h : <T, U>(f: C<T, U>) => U
|
||||
>T : T
|
||||
>U : U
|
||||
>f : C<T, U>
|
||||
>C : C<R, S>
|
||||
>T : T
|
||||
>U : U
|
||||
>U : U
|
||||
|
||||
h([[]] as [void[]]); // U: {}
|
||||
>h([[]] as [void[]]) : {}
|
||||
>h : <T, U>(f: C<T, U>) => U
|
||||
>[[]] as [void[]] : [void[]]
|
||||
>[[]] : [never[]]
|
||||
>[] : never[]
|
||||
|
||||
// Repro from #22562
|
||||
|
||||
type C2<R> = [R[]] | [R[], void];
|
||||
>C2 : C2<R>
|
||||
>R : R
|
||||
>R : R
|
||||
>R : R
|
||||
|
||||
declare function h2<T>(f: C2<T>): T;
|
||||
>h2 : <T>(f: C2<T>) => T
|
||||
>T : T
|
||||
>f : C2<T>
|
||||
>C2 : C2<R>
|
||||
>T : T
|
||||
>T : T
|
||||
|
||||
h2([[]] as [never[]]); // T: never
|
||||
>h2([[]] as [never[]]) : never
|
||||
>h2 : <T>(f: C2<T>) => T
|
||||
>[[]] as [never[]] : [never[]]
|
||||
>[[]] : [never[]]
|
||||
>[] : never[]
|
||||
|
||||
h2([[]] as [void[]]); // T: void
|
||||
>h2([[]] as [void[]]) : void
|
||||
>h2 : <T>(f: C2<T>) => T
|
||||
>[[]] as [void[]] : [void[]]
|
||||
>[[]] : [never[]]
|
||||
>[] : never[]
|
||||
|
||||
25
tests/cases/compiler/tupleTypeInference2.ts
Normal file
25
tests/cases/compiler/tupleTypeInference2.ts
Normal file
@ -0,0 +1,25 @@
|
||||
// @strict: true
|
||||
|
||||
// Repro from #22564
|
||||
|
||||
type A<R> = [R] | [R, string];
|
||||
declare function f<T>(x: A<T>): T;
|
||||
f([undefined, ''] as [never, string]); // T: never
|
||||
f([undefined, ''] as [void, string]); // T: void
|
||||
|
||||
// Repro from #22563
|
||||
|
||||
type B<R, S> = [R] | [R, S];
|
||||
declare function g<T, U>(f: B<T, U>): U;
|
||||
g([[]] as [void[]]); // U: {}
|
||||
|
||||
type C<R, S> = [R[]] | [R[], S];
|
||||
declare function h<T, U>(f: C<T, U>): U;
|
||||
h([[]] as [void[]]); // U: {}
|
||||
|
||||
// Repro from #22562
|
||||
|
||||
type C2<R> = [R[]] | [R[], void];
|
||||
declare function h2<T>(f: C2<T>): T;
|
||||
h2([[]] as [never[]]); // T: never
|
||||
h2([[]] as [void[]]); // T: void
|
||||
Loading…
x
Reference in New Issue
Block a user