mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-11 10:00:13 -06:00
Contextual typing of array literals is now based on the presence or absence
of numerically named properties and doesn't directly test for tuple types.
This commit is contained in:
parent
c0e802deb5
commit
63b83e7c3f
@ -3758,19 +3758,17 @@ module ts {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// In an array literal contextually typed by a type T, the contextual type of an element expression is the corresponding
|
||||
// tuple element type in T, if one exists and T is a tuple type. Otherwise, it is the type of the numeric index signature
|
||||
// in T, if one exists.
|
||||
// In an array literal contextually typed by a type T, the contextual type of an element expression at index N is
|
||||
// the type of the property with the numeric name N in T, if one exists. Otherwise, it is the type of the numeric
|
||||
// index signature in T, if one exists.
|
||||
function getContextualTypeForElementExpression(node: Expression): Type {
|
||||
var arrayLiteral = <ArrayLiteral>node.parent;
|
||||
var type = getContextualType(arrayLiteral);
|
||||
if (type) {
|
||||
if (type.flags & TypeFlags.Tuple) {
|
||||
var index = indexOf(arrayLiteral.elements, node);
|
||||
var prop = getPropertyOfType(type, "" + index);
|
||||
if (prop) {
|
||||
return getTypeOfSymbol(prop);
|
||||
}
|
||||
var index = indexOf(arrayLiteral.elements, node);
|
||||
var prop = getPropertyOfType(type, "" + index);
|
||||
if (prop) {
|
||||
return getTypeOfSymbol(prop);
|
||||
}
|
||||
return getIndexTypeOfType(type, IndexKind.Number);
|
||||
}
|
||||
@ -3837,21 +3835,24 @@ module ts {
|
||||
|
||||
function checkArrayLiteral(node: ArrayLiteral, contextualMapper?: TypeMapper): Type {
|
||||
var contextualType = getContextualType(node);
|
||||
var isTupleLiteral = contextualType && (contextualType.flags & TypeFlags.Tuple) !== 0;
|
||||
var elements = node.elements;
|
||||
var elementTypes: Type[] = [];
|
||||
forEach(node.elements, element => {
|
||||
var type = element.kind !== SyntaxKind.OmittedExpression ? checkExpression(element, contextualMapper) : undefinedType;
|
||||
if (isTupleLiteral || !contains(elementTypes, type)) {
|
||||
elementTypes.push(type);
|
||||
var isTupleLiteral: boolean = false;
|
||||
for (var i = 0; i < elements.length; i++) {
|
||||
if (contextualType && getPropertyOfType(contextualType, "" + i)) {
|
||||
isTupleLiteral = true;
|
||||
}
|
||||
});
|
||||
var element = elements[i];
|
||||
var type = element.kind !== SyntaxKind.OmittedExpression ? checkExpression(element, contextualMapper) : undefinedType;
|
||||
elementTypes.push(type);
|
||||
}
|
||||
if (isTupleLiteral) {
|
||||
return createTupleType(elementTypes);
|
||||
}
|
||||
var contextualElementType = contextualType && !isInferentialContext(contextualMapper) ? getIndexTypeOfType(contextualType, IndexKind.Number) : undefined;
|
||||
var elementType = getBestCommonType(elementTypes, contextualElementType, true);
|
||||
var elementType = getBestCommonType(uniqueElements(elementTypes), contextualElementType, true);
|
||||
if (!elementType) {
|
||||
elementType = elementTypes.length ? emptyObjectType : undefinedType;
|
||||
elementType = elements.length ? emptyObjectType : undefinedType;
|
||||
}
|
||||
return createArrayType(elementType);
|
||||
}
|
||||
|
||||
@ -19,8 +19,7 @@ module ts {
|
||||
|
||||
export function contains<T>(array: T[], value: T): boolean {
|
||||
if (array) {
|
||||
var len = array.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
for (var i = 0, len = array.length; i < len; i++) {
|
||||
if (array[i] === value) {
|
||||
return true;
|
||||
}
|
||||
@ -31,8 +30,7 @@ module ts {
|
||||
|
||||
export function indexOf<T>(array: T[], value: T): number {
|
||||
if (array) {
|
||||
var len = array.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
for (var i = 0, len = array.length; i < len; i++) {
|
||||
if (array[i] === value) {
|
||||
return i;
|
||||
}
|
||||
@ -42,9 +40,8 @@ module ts {
|
||||
}
|
||||
|
||||
export function filter<T>(array: T[], f: (x: T) => boolean): T[] {
|
||||
var result: T[];
|
||||
if (array) {
|
||||
result = [];
|
||||
var result: T[] = [];
|
||||
for (var i = 0, len = array.length; i < len; i++) {
|
||||
var item = array[i];
|
||||
if (f(item)) {
|
||||
@ -56,11 +53,9 @@ module ts {
|
||||
}
|
||||
|
||||
export function map<T, U>(array: T[], f: (x: T) => U): U[] {
|
||||
var result: U[];
|
||||
if (array) {
|
||||
result = [];
|
||||
var len = array.length;
|
||||
for (var i = 0; i < len; i++) {
|
||||
var result: U[] = [];
|
||||
for (var i = 0, len = array.length; i < len; i++) {
|
||||
result.push(f(array[i]));
|
||||
}
|
||||
}
|
||||
@ -73,6 +68,17 @@ module ts {
|
||||
return array1.concat(array2);
|
||||
}
|
||||
|
||||
export function uniqueElements<T>(array: T[]): T[] {
|
||||
if (array) {
|
||||
var result: T[] = [];
|
||||
for (var i = 0, len = array.length; i < len; i++) {
|
||||
var item = array[i];
|
||||
if (!contains(result, item)) result.push(item);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export function sum(array: any[], prop: string): number {
|
||||
var result = 0;
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
|
||||
@ -16,8 +16,8 @@
|
||||
|
||||
t = []; // Error
|
||||
~
|
||||
!!! Type '[]' is not assignable to type '[number, string]':
|
||||
!!! Property '0' is missing in type '[]'.
|
||||
!!! Type '{}[]' is not assignable to type '[number, string]':
|
||||
!!! Property '0' is missing in type '{}[]'.
|
||||
t = [1]; // Error
|
||||
~
|
||||
!!! Type '[number]' is not assignable to type '[number, string]':
|
||||
@ -53,7 +53,7 @@
|
||||
tt = [undefined, undefined];
|
||||
tt = []; // Error
|
||||
~~
|
||||
!!! Type '[]' is not assignable to type '[number, string]'.
|
||||
!!! Type '{}[]' is not assignable to type '[number, string]'.
|
||||
|
||||
var a: number[];
|
||||
var a1: [number, string];
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user