Include index signatures of the source in mapped type template target inferences (#29253)

This commit is contained in:
Wesley Wigham 2019-01-25 15:22:35 -08:00 committed by GitHub
parent 5f782bf58a
commit 4da9d8bc87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 54 additions and 3 deletions

View File

@ -14574,7 +14574,12 @@ namespace ts {
priority |= InferencePriority.MappedTypeConstraint;
inferFromTypes(getIndexType(source), constraintType);
priority = savePriority;
inferFromTypes(getUnionType(map(getPropertiesOfType(source), getTypeOfSymbol)), getTemplateTypeFromMappedType(<MappedType>target));
const valueTypes = compact([
getIndexTypeOfType(source, IndexKind.String),
getIndexTypeOfType(source, IndexKind.Number),
...map(getPropertiesOfType(source), getTypeOfSymbol)
]);
inferFromTypes(getUnionType(valueTypes), getTemplateTypeFromMappedType(<MappedType>target));
return true;
}
return false;

View File

@ -884,8 +884,11 @@ namespace ts {
/**
* Compacts an array, removing any falsey elements.
*/
export function compact<T>(array: T[]): T[];
export function compact<T>(array: ReadonlyArray<T>): ReadonlyArray<T>;
export function compact<T>(array: (T | undefined | null | false | 0 | "")[]): T[];
export function compact<T>(array: ReadonlyArray<T | undefined | null | false | 0 | "">): ReadonlyArray<T>;
// TSLint thinks these can be combined with the above - they cannot; they'd produce higher-priority inferences and prevent the falsey types from being stripped
export function compact<T>(array: T[]): T[]; // tslint:disable-line unified-signatures
export function compact<T>(array: ReadonlyArray<T>): ReadonlyArray<T>; // tslint:disable-line unified-signatures
export function compact<T>(array: T[]): T[] {
let result: T[] | undefined;
if (array) {

View File

@ -0,0 +1,8 @@
//// [mappedToToIndexSignatureInference.ts]
declare const fn: <K extends string, V>(object: { [Key in K]: V }) => object;
declare const a: { [index: string]: number };
fn(a);
//// [mappedToToIndexSignatureInference.js]
fn(a);

View File

@ -0,0 +1,18 @@
=== tests/cases/compiler/mappedToToIndexSignatureInference.ts ===
declare const fn: <K extends string, V>(object: { [Key in K]: V }) => object;
>fn : Symbol(fn, Decl(mappedToToIndexSignatureInference.ts, 0, 13))
>K : Symbol(K, Decl(mappedToToIndexSignatureInference.ts, 0, 19))
>V : Symbol(V, Decl(mappedToToIndexSignatureInference.ts, 0, 36))
>object : Symbol(object, Decl(mappedToToIndexSignatureInference.ts, 0, 40))
>Key : Symbol(Key, Decl(mappedToToIndexSignatureInference.ts, 0, 51))
>K : Symbol(K, Decl(mappedToToIndexSignatureInference.ts, 0, 19))
>V : Symbol(V, Decl(mappedToToIndexSignatureInference.ts, 0, 36))
declare const a: { [index: string]: number };
>a : Symbol(a, Decl(mappedToToIndexSignatureInference.ts, 1, 13))
>index : Symbol(index, Decl(mappedToToIndexSignatureInference.ts, 1, 20))
fn(a);
>fn : Symbol(fn, Decl(mappedToToIndexSignatureInference.ts, 0, 13))
>a : Symbol(a, Decl(mappedToToIndexSignatureInference.ts, 1, 13))

View File

@ -0,0 +1,14 @@
=== tests/cases/compiler/mappedToToIndexSignatureInference.ts ===
declare const fn: <K extends string, V>(object: { [Key in K]: V }) => object;
>fn : <K extends string, V>(object: { [Key in K]: V; }) => object
>object : { [Key in K]: V; }
declare const a: { [index: string]: number };
>a : { [index: string]: number; }
>index : string
fn(a);
>fn(a) : object
>fn : <K extends string, V>(object: { [Key in K]: V; }) => object
>a : { [index: string]: number; }

View File

@ -0,0 +1,3 @@
declare const fn: <K extends string, V>(object: { [Key in K]: V }) => object;
declare const a: { [index: string]: number };
fn(a);