Skip to content

Commit

Permalink
Include index signatures of the source in mapped type template target…
Browse files Browse the repository at this point in the history
… inferences (#29253)
  • Loading branch information
weswigham committed Jan 25, 2019
1 parent 5f782bf commit 4da9d8b
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 3 deletions.
7 changes: 6 additions & 1 deletion src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
7 changes: 5 additions & 2 deletions src/compiler/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
Original file line number Diff line number Diff line change
@@ -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))

14 changes: 14 additions & 0 deletions tests/baselines/reference/mappedToToIndexSignatureInference.types
Original file line number Diff line number Diff line change
@@ -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; }

3 changes: 3 additions & 0 deletions tests/cases/compiler/mappedToToIndexSignatureInference.ts
Original file line number Diff line number Diff line change
@@ -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);

0 comments on commit 4da9d8b

Please sign in to comment.