Merge pull request #21610 from Microsoft/fixSharedTypeParameters

Fix unintended sharing of type parameters
This commit is contained in:
Anders Hejlsberg 2018-02-05 11:20:34 -08:00 committed by GitHub
commit d629607f98
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 118 additions and 2 deletions

View File

@ -8705,7 +8705,7 @@ namespace ts {
const target = type.objectFlags & ObjectFlags.Instantiated ? type.target : type;
const symbol = target.symbol;
const links = getSymbolLinks(symbol);
let typeParameters = links.typeParameters;
let typeParameters = links.outerTypeParameters;
if (!typeParameters) {
// The first time an anonymous type is instantiated we compute and store a list of the type
// parameters that are in scope (and therefore potentially referenced). For type literals that
@ -8716,7 +8716,7 @@ namespace ts {
typeParameters = symbol.flags & SymbolFlags.TypeLiteral && !target.aliasTypeArguments ?
filter(outerTypeParameters, tp => isTypeParameterPossiblyReferenced(tp, declaration)) :
outerTypeParameters;
links.typeParameters = typeParameters;
links.outerTypeParameters = typeParameters;
if (typeParameters.length) {
links.instantiations = createMap<Type>();
links.instantiations.set(getTypeListId(typeParameters), target);

View File

@ -3312,6 +3312,7 @@ namespace ts {
type?: Type; // Type of value symbol
declaredType?: Type; // Type of class, interface, enum, type alias, or type parameter
typeParameters?: TypeParameter[]; // Type parameters of type alias (undefined if non-generic)
outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type
inferredClassType?: Type; // Type of an inferred ES5 class
instantiations?: Map<Type>; // Instantiations of generic type alias (undefined if non-generic)
mapper?: TypeMapper; // Type mapper for instantiation alias

View File

@ -0,0 +1,36 @@
//// [typeAliasFunctionTypeSharedSymbol.ts]
// Repro from comment in #21496
function Mixin<TBase extends {new (...args: any[]): {}}>(Base: TBase) {
return class extends Base {
};
}
type Mixin = ReturnTypeOf<typeof Mixin>
type ReturnTypeOf<V> = V extends (...args: any[])=>infer R ? R : never;
type Crashes = number & Mixin;
//// [typeAliasFunctionTypeSharedSymbol.js]
// Repro from comment in #21496
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
function Mixin(Base) {
return /** @class */ (function (_super) {
__extends(class_1, _super);
function class_1() {
return _super !== null && _super.apply(this, arguments) || this;
}
return class_1;
}(Base));
}

View File

@ -0,0 +1,33 @@
=== tests/cases/compiler/typeAliasFunctionTypeSharedSymbol.ts ===
// Repro from comment in #21496
function Mixin<TBase extends {new (...args: any[]): {}}>(Base: TBase) {
>Mixin : Symbol(Mixin, Decl(typeAliasFunctionTypeSharedSymbol.ts, 0, 0), Decl(typeAliasFunctionTypeSharedSymbol.ts, 5, 1))
>TBase : Symbol(TBase, Decl(typeAliasFunctionTypeSharedSymbol.ts, 2, 15))
>args : Symbol(args, Decl(typeAliasFunctionTypeSharedSymbol.ts, 2, 35))
>Base : Symbol(Base, Decl(typeAliasFunctionTypeSharedSymbol.ts, 2, 57))
>TBase : Symbol(TBase, Decl(typeAliasFunctionTypeSharedSymbol.ts, 2, 15))
return class extends Base {
>Base : Symbol(Base, Decl(typeAliasFunctionTypeSharedSymbol.ts, 2, 57))
};
}
type Mixin = ReturnTypeOf<typeof Mixin>
>Mixin : Symbol(Mixin, Decl(typeAliasFunctionTypeSharedSymbol.ts, 0, 0), Decl(typeAliasFunctionTypeSharedSymbol.ts, 5, 1))
>ReturnTypeOf : Symbol(ReturnTypeOf, Decl(typeAliasFunctionTypeSharedSymbol.ts, 7, 39))
>Mixin : Symbol(Mixin, Decl(typeAliasFunctionTypeSharedSymbol.ts, 0, 0), Decl(typeAliasFunctionTypeSharedSymbol.ts, 5, 1))
type ReturnTypeOf<V> = V extends (...args: any[])=>infer R ? R : never;
>ReturnTypeOf : Symbol(ReturnTypeOf, Decl(typeAliasFunctionTypeSharedSymbol.ts, 7, 39))
>V : Symbol(V, Decl(typeAliasFunctionTypeSharedSymbol.ts, 9, 18))
>V : Symbol(V, Decl(typeAliasFunctionTypeSharedSymbol.ts, 9, 18))
>args : Symbol(args, Decl(typeAliasFunctionTypeSharedSymbol.ts, 9, 34))
>R : Symbol(R, Decl(typeAliasFunctionTypeSharedSymbol.ts, 9, 56))
>R : Symbol(R, Decl(typeAliasFunctionTypeSharedSymbol.ts, 9, 56))
type Crashes = number & Mixin;
>Crashes : Symbol(Crashes, Decl(typeAliasFunctionTypeSharedSymbol.ts, 9, 71))
>Mixin : Symbol(Mixin, Decl(typeAliasFunctionTypeSharedSymbol.ts, 0, 0), Decl(typeAliasFunctionTypeSharedSymbol.ts, 5, 1))

View File

@ -0,0 +1,34 @@
=== tests/cases/compiler/typeAliasFunctionTypeSharedSymbol.ts ===
// Repro from comment in #21496
function Mixin<TBase extends {new (...args: any[]): {}}>(Base: TBase) {
>Mixin : <TBase extends new (...args: any[]) => {}>(Base: TBase) => { new (...args: any[]): (Anonymous class); prototype: Mixin<any>.(Anonymous class); } & TBase
>TBase : TBase
>args : any[]
>Base : TBase
>TBase : TBase
return class extends Base {
>class extends Base { } : { new (...args: any[]): (Anonymous class); prototype: Mixin<any>.(Anonymous class); } & TBase
>Base : {}
};
}
type Mixin = ReturnTypeOf<typeof Mixin>
>Mixin : { new (...args: any[]): Mixin<new (...args: any[]) => {}>.(Anonymous class); prototype: Mixin<any>.(Anonymous class); } & (new (...args: any[]) => {})
>ReturnTypeOf : ReturnTypeOf<V>
>Mixin : <TBase extends new (...args: any[]) => {}>(Base: TBase) => { new (...args: any[]): (Anonymous class); prototype: Mixin<any>.(Anonymous class); } & TBase
type ReturnTypeOf<V> = V extends (...args: any[])=>infer R ? R : never;
>ReturnTypeOf : ReturnTypeOf<V>
>V : V
>V : V
>args : any[]
>R : R
>R : R
type Crashes = number & Mixin;
>Crashes : Crashes
>Mixin : { new (...args: any[]): Mixin<new (...args: any[]) => {}>.(Anonymous class); prototype: Mixin<any>.(Anonymous class); } & (new (...args: any[]) => {})

View File

@ -0,0 +1,12 @@
// Repro from comment in #21496
function Mixin<TBase extends {new (...args: any[]): {}}>(Base: TBase) {
return class extends Base {
};
}
type Mixin = ReturnTypeOf<typeof Mixin>
type ReturnTypeOf<V> = V extends (...args: any[])=>infer R ? R : never;
type Crashes = number & Mixin;