Add comment explaining type alias instantiation strategy

This commit is contained in:
Anders Hejlsberg 2016-11-13 15:25:16 -08:00
parent 6ceab7bce7
commit cd05c079ce

View File

@ -6519,6 +6519,23 @@ namespace ts {
function instantiateType(type: Type, mapper: TypeMapper): Type {
if (type && mapper !== identityMapper) {
// If we are instantiating a type that has a top-level type alias, obtain the instantiation through
// the type alias instead in order to share instantiations for the same type arguments. This can
// dramatically reduce the number of structurally identical types we generate. Note that we can only
// perform this optimization for top-level type aliases. Consider:
//
// function f1<T>(x: T) {
// type Foo<X> = { x: X, t: T };
// let obj: Foo<T> = { x: x };
// return obj;
// }
// function f2<U>(x: U) { return f1(x); }
// let z = f2(42);
//
// Above, the declaration of f2 has an inferred return type that is an instantiation of f1's Foo<X>
// equivalent to { x: U, t: U }. When instantiating this return type, we can't go back to Foo<X>'s
// cache because all cached instantiations are of the form { x: ???, t: T }, i.e. they have not been
// instantiated for T. Instead, we need to further instantiate the { x: U, t: U } form.
if (type.aliasSymbol && isTopLevelTypeAlias(type.aliasSymbol)) {
if (type.aliasTypeArguments) {
return getTypeAliasInstantiation(type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));