Add ability to infer to the simplified form of a type variable (#27953)
* Add ability to infer to the simplified form of a type variable * Add test
This commit is contained in:
parent
7b5ef64e76
commit
9554f09d09
|
@ -13644,6 +13644,17 @@ namespace ts {
|
|||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
// Infer to the simplified version of an indexed access, if possible, to (hopefully) expose more bare type parameters to the inference engine
|
||||
const simplified = getSimplifiedType(target);
|
||||
if (simplified !== target) {
|
||||
const key = source.id + "," + simplified.id;
|
||||
if (!visited || !visited.get(key)) {
|
||||
(visited || (visited = createMap<boolean>())).set(key, true);
|
||||
inferFromTypes(source, simplified);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (<TypeReference>source).target === (<TypeReference>target).target) {
|
||||
// If source and target are references to the same generic type, infer from type arguments
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
//// [complicatedIndexesOfIntersectionsAreInferencable.ts]
|
||||
interface FormikConfig<Values> {
|
||||
initialValues: Values;
|
||||
validate?: (props: Values) => void;
|
||||
validateOnChange?: boolean;
|
||||
}
|
||||
|
||||
declare function Func<Values = object, ExtraProps = {}>(
|
||||
x: (string extends "validate" | "initialValues" | keyof ExtraProps
|
||||
? Readonly<FormikConfig<Values> & ExtraProps>
|
||||
: Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validate" | "initialValues" | Exclude<keyof ExtraProps, "validateOnChange">>
|
||||
& Partial<Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validateOnChange" | Extract<keyof ExtraProps, "validateOnChange">>>)
|
||||
): void;
|
||||
|
||||
Func({
|
||||
initialValues: {
|
||||
foo: ""
|
||||
},
|
||||
validate: props => {
|
||||
props.foo;
|
||||
}
|
||||
});
|
||||
|
||||
//// [complicatedIndexesOfIntersectionsAreInferencable.js]
|
||||
"use strict";
|
||||
Func({
|
||||
initialValues: {
|
||||
foo: ""
|
||||
},
|
||||
validate: function (props) {
|
||||
props.foo;
|
||||
}
|
||||
});
|
|
@ -0,0 +1,74 @@
|
|||
=== tests/cases/compiler/complicatedIndexesOfIntersectionsAreInferencable.ts ===
|
||||
interface FormikConfig<Values> {
|
||||
>FormikConfig : Symbol(FormikConfig, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 0, 0))
|
||||
>Values : Symbol(Values, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 0, 23))
|
||||
|
||||
initialValues: Values;
|
||||
>initialValues : Symbol(FormikConfig.initialValues, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 0, 32))
|
||||
>Values : Symbol(Values, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 0, 23))
|
||||
|
||||
validate?: (props: Values) => void;
|
||||
>validate : Symbol(FormikConfig.validate, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 1, 26))
|
||||
>props : Symbol(props, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 2, 16))
|
||||
>Values : Symbol(Values, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 0, 23))
|
||||
|
||||
validateOnChange?: boolean;
|
||||
>validateOnChange : Symbol(FormikConfig.validateOnChange, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 2, 39))
|
||||
}
|
||||
|
||||
declare function Func<Values = object, ExtraProps = {}>(
|
||||
>Func : Symbol(Func, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 4, 1))
|
||||
>Values : Symbol(Values, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 6, 22))
|
||||
>ExtraProps : Symbol(ExtraProps, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 6, 38))
|
||||
|
||||
x: (string extends "validate" | "initialValues" | keyof ExtraProps
|
||||
>x : Symbol(x, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 6, 56))
|
||||
>ExtraProps : Symbol(ExtraProps, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 6, 38))
|
||||
|
||||
? Readonly<FormikConfig<Values> & ExtraProps>
|
||||
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
|
||||
>FormikConfig : Symbol(FormikConfig, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 0, 0))
|
||||
>Values : Symbol(Values, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 6, 22))
|
||||
>ExtraProps : Symbol(ExtraProps, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 6, 38))
|
||||
|
||||
: Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validate" | "initialValues" | Exclude<keyof ExtraProps, "validateOnChange">>
|
||||
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
|
||||
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
|
||||
>FormikConfig : Symbol(FormikConfig, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 0, 0))
|
||||
>Values : Symbol(Values, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 6, 22))
|
||||
>ExtraProps : Symbol(ExtraProps, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 6, 38))
|
||||
>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --))
|
||||
>ExtraProps : Symbol(ExtraProps, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 6, 38))
|
||||
|
||||
& Partial<Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validateOnChange" | Extract<keyof ExtraProps, "validateOnChange">>>)
|
||||
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
|
||||
>Pick : Symbol(Pick, Decl(lib.es5.d.ts, --, --))
|
||||
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
|
||||
>FormikConfig : Symbol(FormikConfig, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 0, 0))
|
||||
>Values : Symbol(Values, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 6, 22))
|
||||
>ExtraProps : Symbol(ExtraProps, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 6, 38))
|
||||
>Extract : Symbol(Extract, Decl(lib.es5.d.ts, --, --))
|
||||
>ExtraProps : Symbol(ExtraProps, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 6, 38))
|
||||
|
||||
): void;
|
||||
|
||||
Func({
|
||||
>Func : Symbol(Func, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 4, 1))
|
||||
|
||||
initialValues: {
|
||||
>initialValues : Symbol(initialValues, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 13, 6))
|
||||
|
||||
foo: ""
|
||||
>foo : Symbol(foo, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 14, 20))
|
||||
|
||||
},
|
||||
validate: props => {
|
||||
>validate : Symbol(validate, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 16, 6))
|
||||
>props : Symbol(props, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 17, 13))
|
||||
|
||||
props.foo;
|
||||
>props.foo : Symbol(foo, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 14, 20))
|
||||
>props : Symbol(props, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 17, 13))
|
||||
>foo : Symbol(foo, Decl(complicatedIndexesOfIntersectionsAreInferencable.ts, 14, 20))
|
||||
}
|
||||
});
|
|
@ -0,0 +1,49 @@
|
|||
=== tests/cases/compiler/complicatedIndexesOfIntersectionsAreInferencable.ts ===
|
||||
interface FormikConfig<Values> {
|
||||
initialValues: Values;
|
||||
>initialValues : Values
|
||||
|
||||
validate?: (props: Values) => void;
|
||||
>validate : ((props: Values) => void) | undefined
|
||||
>props : Values
|
||||
|
||||
validateOnChange?: boolean;
|
||||
>validateOnChange : boolean | undefined
|
||||
}
|
||||
|
||||
declare function Func<Values = object, ExtraProps = {}>(
|
||||
>Func : <Values = object, ExtraProps = {}>(x: string extends "validate" | "initialValues" | keyof ExtraProps ? Readonly<FormikConfig<Values> & ExtraProps> : Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validate" | "initialValues" | Exclude<keyof ExtraProps, "validateOnChange">> & Partial<Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validateOnChange" | Extract<keyof ExtraProps, "validateOnChange">>>) => void
|
||||
|
||||
x: (string extends "validate" | "initialValues" | keyof ExtraProps
|
||||
>x : string extends "validate" | "initialValues" | keyof ExtraProps ? Readonly<FormikConfig<Values> & ExtraProps> : Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validate" | "initialValues" | Exclude<keyof ExtraProps, "validateOnChange">> & Partial<Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validateOnChange" | Extract<keyof ExtraProps, "validateOnChange">>>
|
||||
|
||||
? Readonly<FormikConfig<Values> & ExtraProps>
|
||||
: Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validate" | "initialValues" | Exclude<keyof ExtraProps, "validateOnChange">>
|
||||
& Partial<Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validateOnChange" | Extract<keyof ExtraProps, "validateOnChange">>>)
|
||||
): void;
|
||||
|
||||
Func({
|
||||
>Func({ initialValues: { foo: "" }, validate: props => { props.foo; }}) : void
|
||||
>Func : <Values = object, ExtraProps = {}>(x: string extends "validate" | "initialValues" | keyof ExtraProps ? Readonly<FormikConfig<Values> & ExtraProps> : Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validate" | "initialValues" | Exclude<keyof ExtraProps, "validateOnChange">> & Partial<Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validateOnChange" | Extract<keyof ExtraProps, "validateOnChange">>>) => void
|
||||
>{ initialValues: { foo: "" }, validate: props => { props.foo; }} : { initialValues: { foo: string; }; validate: (props: { foo: string; }) => void; }
|
||||
|
||||
initialValues: {
|
||||
>initialValues : { foo: string; }
|
||||
>{ foo: "" } : { foo: string; }
|
||||
|
||||
foo: ""
|
||||
>foo : string
|
||||
>"" : ""
|
||||
|
||||
},
|
||||
validate: props => {
|
||||
>validate : (props: { foo: string; }) => void
|
||||
>props => { props.foo; } : (props: { foo: string; }) => void
|
||||
>props : { foo: string; }
|
||||
|
||||
props.foo;
|
||||
>props.foo : string
|
||||
>props : { foo: string; }
|
||||
>foo : string
|
||||
}
|
||||
});
|
|
@ -0,0 +1,22 @@
|
|||
// @strict: true
|
||||
interface FormikConfig<Values> {
|
||||
initialValues: Values;
|
||||
validate?: (props: Values) => void;
|
||||
validateOnChange?: boolean;
|
||||
}
|
||||
|
||||
declare function Func<Values = object, ExtraProps = {}>(
|
||||
x: (string extends "validate" | "initialValues" | keyof ExtraProps
|
||||
? Readonly<FormikConfig<Values> & ExtraProps>
|
||||
: Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validate" | "initialValues" | Exclude<keyof ExtraProps, "validateOnChange">>
|
||||
& Partial<Pick<Readonly<FormikConfig<Values> & ExtraProps>, "validateOnChange" | Extract<keyof ExtraProps, "validateOnChange">>>)
|
||||
): void;
|
||||
|
||||
Func({
|
||||
initialValues: {
|
||||
foo: ""
|
||||
},
|
||||
validate: props => {
|
||||
props.foo;
|
||||
}
|
||||
});
|
Loading…
Reference in a new issue