From c5db1614f64653c9455f3fadf3863fa8f252b61c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 22 Jul 2014 11:53:06 -0700 Subject: [PATCH] Aligning index signature type inference with assignability rules. Type inference now supports inferring from string index signatures to numeric index signatures. Fixes #167. --- src/compiler/checker.ts | 11 +++---- .../indexSignatureTypeInference.errors.txt | 23 ++++++++++++++ .../reference/indexSignatureTypeInference.js | 30 +++++++++++++++++++ .../compiler/indexSignatureTypeInference.ts | 19 ++++++++++++ 4 files changed, 78 insertions(+), 5 deletions(-) create mode 100644 tests/baselines/reference/indexSignatureTypeInference.errors.txt create mode 100644 tests/baselines/reference/indexSignatureTypeInference.js create mode 100644 tests/cases/compiler/indexSignatureTypeInference.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index aa457833175b6..086be15190bca 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3075,8 +3075,9 @@ module ts { inferFromProperties(source, target); inferFromSignatures(source, target, SignatureKind.Call); inferFromSignatures(source, target, SignatureKind.Construct); - inferFromIndexTypes(source, target, IndexKind.String); - inferFromIndexTypes(source, target, IndexKind.Number); + inferFromIndexTypes(source, target, IndexKind.String, IndexKind.String); + inferFromIndexTypes(source, target, IndexKind.Number, IndexKind.Number); + inferFromIndexTypes(source, target, IndexKind.String, IndexKind.Number); depth--; } } @@ -3109,10 +3110,10 @@ module ts { inferFromTypes(getReturnTypeOfSignature(source), getReturnTypeOfSignature(target)); } - function inferFromIndexTypes(source: Type, target: Type, kind: IndexKind) { - var targetIndexType = getIndexTypeOfType(target, kind); + function inferFromIndexTypes(source: Type, target: Type, sourceKind: IndexKind, targetKind: IndexKind) { + var targetIndexType = getIndexTypeOfType(target, targetKind); if (targetIndexType) { - var sourceIndexType = getIndexTypeOfType(source, kind); + var sourceIndexType = getIndexTypeOfType(source, sourceKind); if (sourceIndexType) { inferFromTypes(sourceIndexType, targetIndexType); } diff --git a/tests/baselines/reference/indexSignatureTypeInference.errors.txt b/tests/baselines/reference/indexSignatureTypeInference.errors.txt new file mode 100644 index 0000000000000..097fef70921d8 --- /dev/null +++ b/tests/baselines/reference/indexSignatureTypeInference.errors.txt @@ -0,0 +1,23 @@ +==== tests/cases/compiler/indexSignatureTypeInference.ts (1 errors) ==== + interface NumberMap { + [index: number]: T; + } + + interface StringMap { + [index: string]: T; + } + + declare function numberMapToArray(object: NumberMap): T[]; + declare function stringMapToArray(object: StringMap): T[]; + + var numberMap: NumberMap; + var stringMap: StringMap; + + var v1: Function[]; + var v1 = numberMapToArray(numberMap); // Ok + var v1 = numberMapToArray(stringMap); // Ok + var v1 = stringMapToArray(numberMap); // Error expected here + ~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! Supplied parameters do not match any signature of call target. + var v1 = stringMapToArray(stringMap); // Ok + \ No newline at end of file diff --git a/tests/baselines/reference/indexSignatureTypeInference.js b/tests/baselines/reference/indexSignatureTypeInference.js new file mode 100644 index 0000000000000..a4f798012584c --- /dev/null +++ b/tests/baselines/reference/indexSignatureTypeInference.js @@ -0,0 +1,30 @@ +//// [indexSignatureTypeInference.ts] +interface NumberMap { + [index: number]: T; +} + +interface StringMap { + [index: string]: T; +} + +declare function numberMapToArray(object: NumberMap): T[]; +declare function stringMapToArray(object: StringMap): T[]; + +var numberMap: NumberMap; +var stringMap: StringMap; + +var v1: Function[]; +var v1 = numberMapToArray(numberMap); // Ok +var v1 = numberMapToArray(stringMap); // Ok +var v1 = stringMapToArray(numberMap); // Error expected here +var v1 = stringMapToArray(stringMap); // Ok + + +//// [indexSignatureTypeInference.js] +var numberMap; +var stringMap; +var v1; +var v1 = numberMapToArray(numberMap); +var v1 = numberMapToArray(stringMap); +var v1 = stringMapToArray(numberMap); +var v1 = stringMapToArray(stringMap); diff --git a/tests/cases/compiler/indexSignatureTypeInference.ts b/tests/cases/compiler/indexSignatureTypeInference.ts new file mode 100644 index 0000000000000..66fcb53d76c71 --- /dev/null +++ b/tests/cases/compiler/indexSignatureTypeInference.ts @@ -0,0 +1,19 @@ +interface NumberMap { + [index: number]: T; +} + +interface StringMap { + [index: string]: T; +} + +declare function numberMapToArray(object: NumberMap): T[]; +declare function stringMapToArray(object: StringMap): T[]; + +var numberMap: NumberMap; +var stringMap: StringMap; + +var v1: Function[]; +var v1 = numberMapToArray(numberMap); // Ok +var v1 = numberMapToArray(stringMap); // Ok +var v1 = stringMapToArray(numberMap); // Error expected here +var v1 = stringMapToArray(stringMap); // Ok