mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-08 02:46:15 -05:00
Merge pull request #22989 from Microsoft/fixImpliedConstraint
Fix implied constraints in conditional types
This commit is contained in:
@@ -7407,7 +7407,7 @@ namespace ts {
|
||||
|
||||
function getConstrainedTypeVariable(typeVariable: TypeVariable, node: Node) {
|
||||
let constraints: Type[];
|
||||
while (isPartOfTypeNode(node)) {
|
||||
while (node && !isStatement(node)) {
|
||||
const parent = node.parent;
|
||||
if (parent.kind === SyntaxKind.ConditionalType && node === (<ConditionalTypeNode>parent).trueType) {
|
||||
const constraint = getImpliedConstraint(typeVariable, (<ConditionalTypeNode>parent).checkType, (<ConditionalTypeNode>parent).extendsType);
|
||||
@@ -8356,17 +8356,17 @@ namespace ts {
|
||||
// resolution of the conditional type such that a later instantiation will properly distribute
|
||||
// over union types.
|
||||
const isDeferred = root.isDistributive && maybeTypeOfKind(checkType, TypeFlags.Instantiable);
|
||||
let combinedMapper: TypeMapper;
|
||||
if (root.inferTypeParameters) {
|
||||
const context = createInferenceContext(root.inferTypeParameters, /*signature*/ undefined, InferenceFlags.None);
|
||||
let combinedMapper: TypeMapper;
|
||||
if (root.inferTypeParameters) {
|
||||
const context = createInferenceContext(root.inferTypeParameters, /*signature*/ undefined, InferenceFlags.None);
|
||||
if (!isDeferred) {
|
||||
// We don't want inferences from constraints as they may cause us to eagerly resolve the
|
||||
// conditional type instead of deferring resolution. Also, we always want strict function
|
||||
// types rules (i.e. proper contravariance) for inferences.
|
||||
inferTypes(context.inferences, checkType, extendsType, InferencePriority.NoConstraints | InferencePriority.AlwaysStrict);
|
||||
}
|
||||
combinedMapper = combineTypeMappers(mapper, context);
|
||||
}
|
||||
combinedMapper = combineTypeMappers(mapper, context);
|
||||
}
|
||||
if (!isDeferred) {
|
||||
// Return union of trueType and falseType for 'any' since it matches anything
|
||||
if (checkType.flags & TypeFlags.Any) {
|
||||
|
||||
@@ -501,4 +501,16 @@ tests/cases/conformance/types/conditional/conditionalTypes1.ts(288,43): error TS
|
||||
type Extracted<Struct> = {
|
||||
[K in keyof Struct]: Struct[K] extends FooBar ? ExtractFooBar<Struct[K]> : Struct[K];
|
||||
}
|
||||
|
||||
// Repro from #22985
|
||||
|
||||
type RecursivePartial<T> = {
|
||||
[P in keyof T]?: T[P] extends Array<any> ? {[index: number]: RecursivePartial<T[P][0]>} :
|
||||
T[P] extends object ? RecursivePartial<T[P]> : T[P];
|
||||
};
|
||||
|
||||
declare function assign<T>(o: T, a: RecursivePartial<T>): void;
|
||||
|
||||
var a = {o: 1, b: 2, c: [{a: 1, c: '213'}]}
|
||||
assign(a, {o: 2, c: {0: {a: 2, c: '213123'}}})
|
||||
|
||||
@@ -339,6 +339,18 @@ declare interface ExtractFooBar<FB extends FooBar> { }
|
||||
type Extracted<Struct> = {
|
||||
[K in keyof Struct]: Struct[K] extends FooBar ? ExtractFooBar<Struct[K]> : Struct[K];
|
||||
}
|
||||
|
||||
// Repro from #22985
|
||||
|
||||
type RecursivePartial<T> = {
|
||||
[P in keyof T]?: T[P] extends Array<any> ? {[index: number]: RecursivePartial<T[P][0]>} :
|
||||
T[P] extends object ? RecursivePartial<T[P]> : T[P];
|
||||
};
|
||||
|
||||
declare function assign<T>(o: T, a: RecursivePartial<T>): void;
|
||||
|
||||
var a = {o: 1, b: 2, c: [{a: 1, c: '213'}]}
|
||||
assign(a, {o: 2, c: {0: {a: 2, c: '213123'}}})
|
||||
|
||||
|
||||
//// [conditionalTypes1.js]
|
||||
@@ -435,6 +447,8 @@ var f45 = function (value) { return value; }; // Error
|
||||
// Repro from #21863
|
||||
function f50() {
|
||||
}
|
||||
var a = { o: 1, b: 2, c: [{ a: 1, c: '213' }] };
|
||||
assign(a, { o: 2, c: { 0: { a: 2, c: '213123' } } });
|
||||
|
||||
|
||||
//// [conditionalTypes1.d.ts]
|
||||
@@ -687,3 +701,17 @@ declare interface ExtractFooBar<FB extends FooBar> {
|
||||
declare type Extracted<Struct> = {
|
||||
[K in keyof Struct]: Struct[K] extends FooBar ? ExtractFooBar<Struct[K]> : Struct[K];
|
||||
};
|
||||
declare type RecursivePartial<T> = {
|
||||
[P in keyof T]?: T[P] extends Array<any> ? {
|
||||
[index: number]: RecursivePartial<T[P][0]>;
|
||||
} : T[P] extends object ? RecursivePartial<T[P]> : T[P];
|
||||
};
|
||||
declare function assign<T>(o: T, a: RecursivePartial<T>): void;
|
||||
declare var a: {
|
||||
o: number;
|
||||
b: number;
|
||||
c: {
|
||||
a: number;
|
||||
c: string;
|
||||
}[];
|
||||
};
|
||||
|
||||
@@ -1317,3 +1317,57 @@ type Extracted<Struct> = {
|
||||
>K : Symbol(K, Decl(conditionalTypes1.ts, 338, 5))
|
||||
}
|
||||
|
||||
// Repro from #22985
|
||||
|
||||
type RecursivePartial<T> = {
|
||||
>RecursivePartial : Symbol(RecursivePartial, Decl(conditionalTypes1.ts, 339, 1))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 343, 22))
|
||||
|
||||
[P in keyof T]?: T[P] extends Array<any> ? {[index: number]: RecursivePartial<T[P][0]>} :
|
||||
>P : Symbol(P, Decl(conditionalTypes1.ts, 344, 3))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 343, 22))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 343, 22))
|
||||
>P : Symbol(P, Decl(conditionalTypes1.ts, 344, 3))
|
||||
>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --))
|
||||
>index : Symbol(index, Decl(conditionalTypes1.ts, 344, 47))
|
||||
>RecursivePartial : Symbol(RecursivePartial, Decl(conditionalTypes1.ts, 339, 1))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 343, 22))
|
||||
>P : Symbol(P, Decl(conditionalTypes1.ts, 344, 3))
|
||||
|
||||
T[P] extends object ? RecursivePartial<T[P]> : T[P];
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 343, 22))
|
||||
>P : Symbol(P, Decl(conditionalTypes1.ts, 344, 3))
|
||||
>RecursivePartial : Symbol(RecursivePartial, Decl(conditionalTypes1.ts, 339, 1))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 343, 22))
|
||||
>P : Symbol(P, Decl(conditionalTypes1.ts, 344, 3))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 343, 22))
|
||||
>P : Symbol(P, Decl(conditionalTypes1.ts, 344, 3))
|
||||
|
||||
};
|
||||
|
||||
declare function assign<T>(o: T, a: RecursivePartial<T>): void;
|
||||
>assign : Symbol(assign, Decl(conditionalTypes1.ts, 346, 2))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 348, 24))
|
||||
>o : Symbol(o, Decl(conditionalTypes1.ts, 348, 27))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 348, 24))
|
||||
>a : Symbol(a, Decl(conditionalTypes1.ts, 348, 32))
|
||||
>RecursivePartial : Symbol(RecursivePartial, Decl(conditionalTypes1.ts, 339, 1))
|
||||
>T : Symbol(T, Decl(conditionalTypes1.ts, 348, 24))
|
||||
|
||||
var a = {o: 1, b: 2, c: [{a: 1, c: '213'}]}
|
||||
>a : Symbol(a, Decl(conditionalTypes1.ts, 350, 3))
|
||||
>o : Symbol(o, Decl(conditionalTypes1.ts, 350, 9))
|
||||
>b : Symbol(b, Decl(conditionalTypes1.ts, 350, 14))
|
||||
>c : Symbol(c, Decl(conditionalTypes1.ts, 350, 20))
|
||||
>a : Symbol(a, Decl(conditionalTypes1.ts, 350, 26))
|
||||
>c : Symbol(c, Decl(conditionalTypes1.ts, 350, 31))
|
||||
|
||||
assign(a, {o: 2, c: {0: {a: 2, c: '213123'}}})
|
||||
>assign : Symbol(assign, Decl(conditionalTypes1.ts, 346, 2))
|
||||
>a : Symbol(a, Decl(conditionalTypes1.ts, 350, 3))
|
||||
>o : Symbol(o, Decl(conditionalTypes1.ts, 351, 11))
|
||||
>c : Symbol(c, Decl(conditionalTypes1.ts, 351, 16))
|
||||
>0 : Symbol(0, Decl(conditionalTypes1.ts, 351, 21))
|
||||
>a : Symbol(a, Decl(conditionalTypes1.ts, 351, 25))
|
||||
>c : Symbol(c, Decl(conditionalTypes1.ts, 351, 30))
|
||||
|
||||
|
||||
@@ -1474,3 +1474,71 @@ type Extracted<Struct> = {
|
||||
>K : K
|
||||
}
|
||||
|
||||
// Repro from #22985
|
||||
|
||||
type RecursivePartial<T> = {
|
||||
>RecursivePartial : RecursivePartial<T>
|
||||
>T : T
|
||||
|
||||
[P in keyof T]?: T[P] extends Array<any> ? {[index: number]: RecursivePartial<T[P][0]>} :
|
||||
>P : P
|
||||
>T : T
|
||||
>T : T
|
||||
>P : P
|
||||
>Array : T[]
|
||||
>index : number
|
||||
>RecursivePartial : RecursivePartial<T>
|
||||
>T : T
|
||||
>P : P
|
||||
|
||||
T[P] extends object ? RecursivePartial<T[P]> : T[P];
|
||||
>T : T
|
||||
>P : P
|
||||
>RecursivePartial : RecursivePartial<T>
|
||||
>T : T
|
||||
>P : P
|
||||
>T : T
|
||||
>P : P
|
||||
|
||||
};
|
||||
|
||||
declare function assign<T>(o: T, a: RecursivePartial<T>): void;
|
||||
>assign : <T>(o: T, a: RecursivePartial<T>) => void
|
||||
>T : T
|
||||
>o : T
|
||||
>T : T
|
||||
>a : RecursivePartial<T>
|
||||
>RecursivePartial : RecursivePartial<T>
|
||||
>T : T
|
||||
|
||||
var a = {o: 1, b: 2, c: [{a: 1, c: '213'}]}
|
||||
>a : { o: number; b: number; c: { a: number; c: string; }[]; }
|
||||
>{o: 1, b: 2, c: [{a: 1, c: '213'}]} : { o: number; b: number; c: { a: number; c: string; }[]; }
|
||||
>o : number
|
||||
>1 : 1
|
||||
>b : number
|
||||
>2 : 2
|
||||
>c : { a: number; c: string; }[]
|
||||
>[{a: 1, c: '213'}] : { a: number; c: string; }[]
|
||||
>{a: 1, c: '213'} : { a: number; c: string; }
|
||||
>a : number
|
||||
>1 : 1
|
||||
>c : string
|
||||
>'213' : "213"
|
||||
|
||||
assign(a, {o: 2, c: {0: {a: 2, c: '213123'}}})
|
||||
>assign(a, {o: 2, c: {0: {a: 2, c: '213123'}}}) : void
|
||||
>assign : <T>(o: T, a: RecursivePartial<T>) => void
|
||||
>a : { o: number; b: number; c: { a: number; c: string; }[]; }
|
||||
>{o: 2, c: {0: {a: 2, c: '213123'}}} : { o: number; c: { 0: { a: number; c: string; }; }; }
|
||||
>o : number
|
||||
>2 : 2
|
||||
>c : { 0: { a: number; c: string; }; }
|
||||
>{0: {a: 2, c: '213123'}} : { 0: { a: number; c: string; }; }
|
||||
>0 : { a: number; c: string; }
|
||||
>{a: 2, c: '213123'} : { a: number; c: string; }
|
||||
>a : number
|
||||
>2 : 2
|
||||
>c : string
|
||||
>'213123' : "213123"
|
||||
|
||||
|
||||
@@ -341,3 +341,15 @@ declare interface ExtractFooBar<FB extends FooBar> { }
|
||||
type Extracted<Struct> = {
|
||||
[K in keyof Struct]: Struct[K] extends FooBar ? ExtractFooBar<Struct[K]> : Struct[K];
|
||||
}
|
||||
|
||||
// Repro from #22985
|
||||
|
||||
type RecursivePartial<T> = {
|
||||
[P in keyof T]?: T[P] extends Array<any> ? {[index: number]: RecursivePartial<T[P][0]>} :
|
||||
T[P] extends object ? RecursivePartial<T[P]> : T[P];
|
||||
};
|
||||
|
||||
declare function assign<T>(o: T, a: RecursivePartial<T>): void;
|
||||
|
||||
var a = {o: 1, b: 2, c: [{a: 1, c: '213'}]}
|
||||
assign(a, {o: 2, c: {0: {a: 2, c: '213123'}}})
|
||||
|
||||
Reference in New Issue
Block a user