Merge pull request #10234 from Microsoft/correct-this-in-tuple-type-parameter-constraints
Correct this in tuple type parameter constraints
This commit is contained in:
commit
688e9bc455
|
@ -1538,8 +1538,8 @@ namespace ts {
|
|||
|
||||
function createType(flags: TypeFlags): Type {
|
||||
const result = new Type(checker, flags);
|
||||
result.id = typeCount;
|
||||
typeCount++;
|
||||
result.id = typeCount;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -4000,6 +4000,9 @@ namespace ts {
|
|||
return createTypeReference((<TypeReference>type).target,
|
||||
concatenate((<TypeReference>type).typeArguments, [thisArgument || (<TypeReference>type).target.thisType]));
|
||||
}
|
||||
if (type.flags & TypeFlags.Tuple) {
|
||||
return createTupleType((type as TupleType).elementTypes, thisArgument);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
|
@ -4103,7 +4106,8 @@ namespace ts {
|
|||
function resolveTupleTypeMembers(type: TupleType) {
|
||||
const arrayElementType = getUnionType(type.elementTypes);
|
||||
// Make the tuple type itself the 'this' type by including an extra type argument
|
||||
const arrayType = resolveStructuredTypeMembers(createTypeFromGenericGlobalType(globalArrayType, [arrayElementType, type]));
|
||||
// (Unless it's provided in the case that the tuple is a type parameter constraint)
|
||||
const arrayType = resolveStructuredTypeMembers(createTypeFromGenericGlobalType(globalArrayType, [arrayElementType, type.thisType || type]));
|
||||
const members = createTupleTypeMemberSymbols(type.elementTypes);
|
||||
addInheritedMembers(members, arrayType.properties);
|
||||
setObjectTypeMembers(type, members, arrayType.callSignatures, arrayType.constructSignatures, arrayType.stringIndexInfo, arrayType.numberIndexInfo);
|
||||
|
@ -5230,15 +5234,16 @@ namespace ts {
|
|||
return links.resolvedType;
|
||||
}
|
||||
|
||||
function createTupleType(elementTypes: Type[]) {
|
||||
const id = getTypeListId(elementTypes);
|
||||
return tupleTypes[id] || (tupleTypes[id] = createNewTupleType(elementTypes));
|
||||
function createTupleType(elementTypes: Type[], thisType?: Type) {
|
||||
const id = getTypeListId(elementTypes) + "," + (thisType ? thisType.id : 0);
|
||||
return tupleTypes[id] || (tupleTypes[id] = createNewTupleType(elementTypes, thisType));
|
||||
}
|
||||
|
||||
function createNewTupleType(elementTypes: Type[]) {
|
||||
function createNewTupleType(elementTypes: Type[], thisType?: Type) {
|
||||
const propagatedFlags = getPropagatingFlagsOfTypes(elementTypes, /*excludeKinds*/ 0);
|
||||
const type = <TupleType>createObjectType(TypeFlags.Tuple | propagatedFlags);
|
||||
type.elementTypes = elementTypes;
|
||||
type.thisType = thisType;
|
||||
return type;
|
||||
}
|
||||
|
||||
|
|
|
@ -2371,6 +2371,7 @@ namespace ts {
|
|||
|
||||
export interface TupleType extends ObjectType {
|
||||
elementTypes: Type[]; // Element types
|
||||
thisType?: Type; // This-type of tuple (only needed for tuples that are constraints of type parameters)
|
||||
}
|
||||
|
||||
export interface UnionOrIntersectionType extends Type {
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
//// [thisInTupleTypeParameterConstraints.ts]
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
interface Boolean {}
|
||||
interface IArguments {}
|
||||
interface Function {}
|
||||
interface Number {}
|
||||
interface RegExp {}
|
||||
interface Object {}
|
||||
interface String {}
|
||||
|
||||
interface Array<T> {
|
||||
// 4 methods will run out of memory if this-types are not instantiated
|
||||
// correctly for tuple types that are type parameter constraints
|
||||
map<U>(arg: this): void;
|
||||
reduceRight<U>(arg: this): void;
|
||||
reduce<U>(arg: this): void;
|
||||
reduce2<U>(arg: this): void;
|
||||
}
|
||||
|
||||
declare function f<T extends [(x: number) => number]>(a: T): void;
|
||||
let x: [(x: number) => number];
|
||||
f(x);
|
||||
|
||||
|
||||
//// [thisInTupleTypeParameterConstraints.js]
|
||||
/// <reference no-default-lib="true"/>
|
||||
var x;
|
||||
f(x);
|
|
@ -0,0 +1,66 @@
|
|||
=== tests/cases/compiler/thisInTupleTypeParameterConstraints.ts ===
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
interface Boolean {}
|
||||
>Boolean : Symbol(Boolean, Decl(thisInTupleTypeParameterConstraints.ts, 0, 0))
|
||||
|
||||
interface IArguments {}
|
||||
>IArguments : Symbol(IArguments, Decl(thisInTupleTypeParameterConstraints.ts, 2, 20))
|
||||
|
||||
interface Function {}
|
||||
>Function : Symbol(Function, Decl(thisInTupleTypeParameterConstraints.ts, 3, 23))
|
||||
|
||||
interface Number {}
|
||||
>Number : Symbol(Number, Decl(thisInTupleTypeParameterConstraints.ts, 4, 21))
|
||||
|
||||
interface RegExp {}
|
||||
>RegExp : Symbol(RegExp, Decl(thisInTupleTypeParameterConstraints.ts, 5, 19))
|
||||
|
||||
interface Object {}
|
||||
>Object : Symbol(Object, Decl(thisInTupleTypeParameterConstraints.ts, 6, 19))
|
||||
|
||||
interface String {}
|
||||
>String : Symbol(String, Decl(thisInTupleTypeParameterConstraints.ts, 7, 19))
|
||||
|
||||
interface Array<T> {
|
||||
>Array : Symbol(Array, Decl(thisInTupleTypeParameterConstraints.ts, 8, 19))
|
||||
>T : Symbol(T, Decl(thisInTupleTypeParameterConstraints.ts, 10, 16))
|
||||
|
||||
// 4 methods will run out of memory if this-types are not instantiated
|
||||
// correctly for tuple types that are type parameter constraints
|
||||
map<U>(arg: this): void;
|
||||
>map : Symbol(Array.map, Decl(thisInTupleTypeParameterConstraints.ts, 10, 20))
|
||||
>U : Symbol(U, Decl(thisInTupleTypeParameterConstraints.ts, 13, 8))
|
||||
>arg : Symbol(arg, Decl(thisInTupleTypeParameterConstraints.ts, 13, 11))
|
||||
|
||||
reduceRight<U>(arg: this): void;
|
||||
>reduceRight : Symbol(Array.reduceRight, Decl(thisInTupleTypeParameterConstraints.ts, 13, 28))
|
||||
>U : Symbol(U, Decl(thisInTupleTypeParameterConstraints.ts, 14, 16))
|
||||
>arg : Symbol(arg, Decl(thisInTupleTypeParameterConstraints.ts, 14, 19))
|
||||
|
||||
reduce<U>(arg: this): void;
|
||||
>reduce : Symbol(Array.reduce, Decl(thisInTupleTypeParameterConstraints.ts, 14, 36))
|
||||
>U : Symbol(U, Decl(thisInTupleTypeParameterConstraints.ts, 15, 11))
|
||||
>arg : Symbol(arg, Decl(thisInTupleTypeParameterConstraints.ts, 15, 14))
|
||||
|
||||
reduce2<U>(arg: this): void;
|
||||
>reduce2 : Symbol(Array.reduce2, Decl(thisInTupleTypeParameterConstraints.ts, 15, 31))
|
||||
>U : Symbol(U, Decl(thisInTupleTypeParameterConstraints.ts, 16, 12))
|
||||
>arg : Symbol(arg, Decl(thisInTupleTypeParameterConstraints.ts, 16, 15))
|
||||
}
|
||||
|
||||
declare function f<T extends [(x: number) => number]>(a: T): void;
|
||||
>f : Symbol(f, Decl(thisInTupleTypeParameterConstraints.ts, 17, 1))
|
||||
>T : Symbol(T, Decl(thisInTupleTypeParameterConstraints.ts, 19, 19))
|
||||
>x : Symbol(x, Decl(thisInTupleTypeParameterConstraints.ts, 19, 31))
|
||||
>a : Symbol(a, Decl(thisInTupleTypeParameterConstraints.ts, 19, 54))
|
||||
>T : Symbol(T, Decl(thisInTupleTypeParameterConstraints.ts, 19, 19))
|
||||
|
||||
let x: [(x: number) => number];
|
||||
>x : Symbol(x, Decl(thisInTupleTypeParameterConstraints.ts, 20, 3))
|
||||
>x : Symbol(x, Decl(thisInTupleTypeParameterConstraints.ts, 20, 9))
|
||||
|
||||
f(x);
|
||||
>f : Symbol(f, Decl(thisInTupleTypeParameterConstraints.ts, 17, 1))
|
||||
>x : Symbol(x, Decl(thisInTupleTypeParameterConstraints.ts, 20, 3))
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
=== tests/cases/compiler/thisInTupleTypeParameterConstraints.ts ===
|
||||
/// <reference no-default-lib="true"/>
|
||||
|
||||
interface Boolean {}
|
||||
>Boolean : Boolean
|
||||
|
||||
interface IArguments {}
|
||||
>IArguments : IArguments
|
||||
|
||||
interface Function {}
|
||||
>Function : Function
|
||||
|
||||
interface Number {}
|
||||
>Number : Number
|
||||
|
||||
interface RegExp {}
|
||||
>RegExp : RegExp
|
||||
|
||||
interface Object {}
|
||||
>Object : Object
|
||||
|
||||
interface String {}
|
||||
>String : String
|
||||
|
||||
interface Array<T> {
|
||||
>Array : T[]
|
||||
>T : T
|
||||
|
||||
// 4 methods will run out of memory if this-types are not instantiated
|
||||
// correctly for tuple types that are type parameter constraints
|
||||
map<U>(arg: this): void;
|
||||
>map : <U>(arg: this) => void
|
||||
>U : U
|
||||
>arg : this
|
||||
|
||||
reduceRight<U>(arg: this): void;
|
||||
>reduceRight : <U>(arg: this) => void
|
||||
>U : U
|
||||
>arg : this
|
||||
|
||||
reduce<U>(arg: this): void;
|
||||
>reduce : <U>(arg: this) => void
|
||||
>U : U
|
||||
>arg : this
|
||||
|
||||
reduce2<U>(arg: this): void;
|
||||
>reduce2 : <U>(arg: this) => void
|
||||
>U : U
|
||||
>arg : this
|
||||
}
|
||||
|
||||
declare function f<T extends [(x: number) => number]>(a: T): void;
|
||||
>f : <T extends [(x: number) => number]>(a: T) => void
|
||||
>T : T
|
||||
>x : number
|
||||
>a : T
|
||||
>T : T
|
||||
|
||||
let x: [(x: number) => number];
|
||||
>x : [(x: number) => number]
|
||||
>x : number
|
||||
|
||||
f(x);
|
||||
>f(x) : void
|
||||
>f : <T extends [(x: number) => number]>(a: T) => void
|
||||
>x : [(x: number) => number]
|
||||
|
22
tests/cases/compiler/thisInTupleTypeParameterConstraints.ts
Normal file
22
tests/cases/compiler/thisInTupleTypeParameterConstraints.ts
Normal file
|
@ -0,0 +1,22 @@
|
|||
/// <reference no-default-lib="true"/>
|
||||
|
||||
interface Boolean {}
|
||||
interface IArguments {}
|
||||
interface Function {}
|
||||
interface Number {}
|
||||
interface RegExp {}
|
||||
interface Object {}
|
||||
interface String {}
|
||||
|
||||
interface Array<T> {
|
||||
// 4 methods will run out of memory if this-types are not instantiated
|
||||
// correctly for tuple types that are type parameter constraints
|
||||
map<U>(arg: this): void;
|
||||
reduceRight<U>(arg: this): void;
|
||||
reduce<U>(arg: this): void;
|
||||
reduce2<U>(arg: this): void;
|
||||
}
|
||||
|
||||
declare function f<T extends [(x: number) => number]>(a: T): void;
|
||||
let x: [(x: number) => number];
|
||||
f(x);
|
Loading…
Reference in a new issue