From 6b2c8cb7df20e89b83a882e8071e7df3a41ae0a5 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 20 Jan 2017 20:33:41 -0800 Subject: [PATCH] Defaults for type aliases --- src/compiler/checker.ts | 16 +- src/compiler/diagnosticMessages.json | 2 +- tests/baselines/reference/genericDefaults.js | 62 +++++++ .../reference/genericDefaults.symbols | 132 +++++++++++++++ .../baselines/reference/genericDefaults.types | 160 ++++++++++++++++++ .../genericDefaultsErrors.errors.txt | 6 +- tests/cases/compiler/genericDefaults.ts | 22 +++ 7 files changed, 389 insertions(+), 11 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d3194eb8aa9..2c9fae622a7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5648,7 +5648,7 @@ namespace ts { const links = getSymbolLinks(symbol); const typeParameters = links.typeParameters; const id = getTypeListId(typeArguments); - return links.instantiations[id] || (links.instantiations[id] = instantiateTypeNoAlias(type, createTypeMapper(typeParameters, typeArguments))); + return links.instantiations[id] || (links.instantiations[id] = instantiateTypeNoAlias(type, createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, links.minTypeArgumentCount)))); } // Get type from reference to type alias. When a type alias is generic, the declared type of the type alias may include @@ -16167,6 +16167,9 @@ namespace ts { checkTypeArgumentConstraints(typeParameters, node.typeArguments, minTypeArgumentCount); } } + if (type.flags & TypeFlags.TypeParameter && !(type).isThisType && type.symbol && !isTypeParameterInScope(type, node)) { + error(node, Diagnostics.Type_parameter_0_cannot_be_referenced_outside_of_the_declaration_that_defines_it, symbolToString(type.symbol)); + } if (type.flags & TypeFlags.Enum && !(type).memberTypes && getNodeLinks(node).resolvedSymbol.flags & SymbolFlags.EnumMember) { error(node, Diagnostics.Enum_type_0_has_members_with_initializers_that_are_not_literals, typeToString(type)); } @@ -17583,11 +17586,6 @@ namespace ts { error(node.name, Diagnostics.All_declarations_of_0_must_have_identical_modifiers, declarationNameToString(node.name)); } } - if (type.flags & TypeFlags.TypeParameter && !(type).isThisType && type.symbol) { - if (!isTypeParameterInScope(type, node)) { - error(node.name, Diagnostics.Type_parameter_0_cannot_be_referenced_outside_of_a_declaration_that_defines_it, symbolToString(type.symbol)); - } - } if (node.kind !== SyntaxKind.PropertyDeclaration && node.kind !== SyntaxKind.PropertySignature) { // We know we don't have a binding pattern or computed name here checkExportsOnMergedDeclarations(node); @@ -17605,7 +17603,11 @@ namespace ts { function isTypeParameterInScope(typeParameter: TypeParameter, node: Node) { const parents = map(filter(typeParameter.symbol.declarations, isTypeParameter), node => node.parent); while (node) { - if (isFunctionLike(node) || isClassLike(node) || node.kind === SyntaxKind.InterfaceDeclaration || node.kind === SyntaxKind.TypeAliasDeclaration) { + if (isFunctionLike(node) || + isClassLike(node) || + node.kind === SyntaxKind.InterfaceDeclaration || + node.kind === SyntaxKind.TypeAliasDeclaration || + node.kind === SyntaxKind.MappedType) { if (contains(parents, node)) { return true; } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index ca4162804d0..7d7f73c85e5 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1127,7 +1127,7 @@ "category": "Error", "code": 2366 }, - "Type parameter '{0}' cannot be referenced outside of a declaration that defines it.": { + "Type parameter '{0}' cannot be referenced outside of the declaration that defines it.": { "category": "Error", "code": 2367 }, diff --git a/tests/baselines/reference/genericDefaults.js b/tests/baselines/reference/genericDefaults.js index 496c3894817..31e861eaa35 100644 --- a/tests/baselines/reference/genericDefaults.js +++ b/tests/baselines/reference/genericDefaults.js @@ -111,6 +111,28 @@ const Derived02c00 = new Derived02(); const Derived02c01 = new Derived02(1); const Derived02c02 = new Derived02(); const Derived02c03 = new Derived02(1); + +type t00 = { a: T; } +const t00c00 = (x).a; +const t00c01 = (>x).a; + +type t01 = { a: [T, U]; } +const t01c00 = (>x).a; +const t01c01 = (>x).a; + +type t02 = { a: [T, U]; } +const t02c00 = (>x).a; +const t02c01 = (>x).a; +const t02c02 = (>x).a; +const t02c03 = (>x).a; +const t02c04 = (>x).a; + +type t03 = { a: [T, U]; } +const t03c00 = (>x).a; +const t03c01 = (>x).a; +const t03c02 = (>x).a; +const t03c03 = (>x).a; +const t03c04 = (>x).a; //// [genericDefaults.js] @@ -191,6 +213,20 @@ var Derived02c00 = new Derived02(); var Derived02c01 = new Derived02(1); var Derived02c02 = new Derived02(); var Derived02c03 = new Derived02(1); +var t00c00 = x.a; +var t00c01 = x.a; +var t01c00 = x.a; +var t01c01 = x.a; +var t02c00 = x.a; +var t02c01 = x.a; +var t02c02 = x.a; +var t02c03 = x.a; +var t02c04 = x.a; +var t03c00 = x.a; +var t03c01 = x.a; +var t03c02 = x.a; +var t03c03 = x.a; +var t03c04 = x.a; //// [genericDefaults.d.ts] @@ -337,3 +373,29 @@ declare const Derived02c00: Derived02; declare const Derived02c01: Derived02; declare const Derived02c02: Derived02; declare const Derived02c03: Derived02; +declare type t00 = { + a: T; +}; +declare const t00c00: number; +declare const t00c01: number; +declare type t01 = { + a: [T, U]; +}; +declare const t01c00: [number, number]; +declare const t01c01: [number, string]; +declare type t02 = { + a: [T, U]; +}; +declare const t02c00: [number, number]; +declare const t02c01: [1, 1]; +declare const t02c02: [number, number]; +declare const t02c03: [1, number]; +declare const t02c04: [number, 1]; +declare type t03 = { + a: [T, U]; +}; +declare const t03c00: [number, number]; +declare const t03c01: [1, 1]; +declare const t03c02: [number, number]; +declare const t03c03: [1, 1]; +declare const t03c04: [number, 1]; diff --git a/tests/baselines/reference/genericDefaults.symbols b/tests/baselines/reference/genericDefaults.symbols index 0a633e60612..736fe3b8cb1 100644 --- a/tests/baselines/reference/genericDefaults.symbols +++ b/tests/baselines/reference/genericDefaults.symbols @@ -506,3 +506,135 @@ const Derived02c03 = new Derived02(1); >Derived02c03 : Symbol(Derived02c03, Decl(genericDefaults.ts, 111, 5)) >Derived02 : Symbol(Derived02, Decl(genericDefaults.ts, 105, 46)) +type t00 = { a: T; } +>t00 : Symbol(t00, Decl(genericDefaults.ts, 111, 46)) +>T : Symbol(T, Decl(genericDefaults.ts, 113, 9)) +>a : Symbol(a, Decl(genericDefaults.ts, 113, 24)) +>T : Symbol(T, Decl(genericDefaults.ts, 113, 9)) + +const t00c00 = (x).a; +>t00c00 : Symbol(t00c00, Decl(genericDefaults.ts, 114, 5)) +>(x).a : Symbol(a, Decl(genericDefaults.ts, 113, 24)) +>t00 : Symbol(t00, Decl(genericDefaults.ts, 111, 46)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(a, Decl(genericDefaults.ts, 113, 24)) + +const t00c01 = (>x).a; +>t00c01 : Symbol(t00c01, Decl(genericDefaults.ts, 115, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 113, 24)) +>t00 : Symbol(t00, Decl(genericDefaults.ts, 111, 46)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(a, Decl(genericDefaults.ts, 113, 24)) + +type t01 = { a: [T, U]; } +>t01 : Symbol(t01, Decl(genericDefaults.ts, 115, 34)) +>T : Symbol(T, Decl(genericDefaults.ts, 117, 9)) +>U : Symbol(U, Decl(genericDefaults.ts, 117, 11)) +>T : Symbol(T, Decl(genericDefaults.ts, 117, 9)) +>a : Symbol(a, Decl(genericDefaults.ts, 117, 22)) +>T : Symbol(T, Decl(genericDefaults.ts, 117, 9)) +>U : Symbol(U, Decl(genericDefaults.ts, 117, 11)) + +const t01c00 = (>x).a; +>t01c00 : Symbol(t01c00, Decl(genericDefaults.ts, 118, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 117, 22)) +>t01 : Symbol(t01, Decl(genericDefaults.ts, 115, 34)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(a, Decl(genericDefaults.ts, 117, 22)) + +const t01c01 = (>x).a; +>t01c01 : Symbol(t01c01, Decl(genericDefaults.ts, 119, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 117, 22)) +>t01 : Symbol(t01, Decl(genericDefaults.ts, 115, 34)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(a, Decl(genericDefaults.ts, 117, 22)) + +type t02 = { a: [T, U]; } +>t02 : Symbol(t02, Decl(genericDefaults.ts, 119, 42)) +>T : Symbol(T, Decl(genericDefaults.ts, 121, 9)) +>U : Symbol(U, Decl(genericDefaults.ts, 121, 26)) +>T : Symbol(T, Decl(genericDefaults.ts, 121, 9)) +>a : Symbol(a, Decl(genericDefaults.ts, 121, 37)) +>T : Symbol(T, Decl(genericDefaults.ts, 121, 9)) +>U : Symbol(U, Decl(genericDefaults.ts, 121, 26)) + +const t02c00 = (>x).a; +>t02c00 : Symbol(t02c00, Decl(genericDefaults.ts, 122, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 121, 37)) +>t02 : Symbol(t02, Decl(genericDefaults.ts, 119, 42)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(a, Decl(genericDefaults.ts, 121, 37)) + +const t02c01 = (>x).a; +>t02c01 : Symbol(t02c01, Decl(genericDefaults.ts, 123, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 121, 37)) +>t02 : Symbol(t02, Decl(genericDefaults.ts, 119, 42)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(a, Decl(genericDefaults.ts, 121, 37)) + +const t02c02 = (>x).a; +>t02c02 : Symbol(t02c02, Decl(genericDefaults.ts, 124, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 121, 37)) +>t02 : Symbol(t02, Decl(genericDefaults.ts, 119, 42)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(a, Decl(genericDefaults.ts, 121, 37)) + +const t02c03 = (>x).a; +>t02c03 : Symbol(t02c03, Decl(genericDefaults.ts, 125, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 121, 37)) +>t02 : Symbol(t02, Decl(genericDefaults.ts, 119, 42)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(a, Decl(genericDefaults.ts, 121, 37)) + +const t02c04 = (>x).a; +>t02c04 : Symbol(t02c04, Decl(genericDefaults.ts, 126, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 121, 37)) +>t02 : Symbol(t02, Decl(genericDefaults.ts, 119, 42)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(a, Decl(genericDefaults.ts, 121, 37)) + +type t03 = { a: [T, U]; } +>t03 : Symbol(t03, Decl(genericDefaults.ts, 126, 37)) +>T : Symbol(T, Decl(genericDefaults.ts, 128, 9)) +>U : Symbol(U, Decl(genericDefaults.ts, 128, 26)) +>T : Symbol(T, Decl(genericDefaults.ts, 128, 9)) +>T : Symbol(T, Decl(genericDefaults.ts, 128, 9)) +>a : Symbol(a, Decl(genericDefaults.ts, 128, 47)) +>T : Symbol(T, Decl(genericDefaults.ts, 128, 9)) +>U : Symbol(U, Decl(genericDefaults.ts, 128, 26)) + +const t03c00 = (>x).a; +>t03c00 : Symbol(t03c00, Decl(genericDefaults.ts, 129, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 128, 47)) +>t03 : Symbol(t03, Decl(genericDefaults.ts, 126, 37)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(a, Decl(genericDefaults.ts, 128, 47)) + +const t03c01 = (>x).a; +>t03c01 : Symbol(t03c01, Decl(genericDefaults.ts, 130, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 128, 47)) +>t03 : Symbol(t03, Decl(genericDefaults.ts, 126, 37)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(a, Decl(genericDefaults.ts, 128, 47)) + +const t03c02 = (>x).a; +>t03c02 : Symbol(t03c02, Decl(genericDefaults.ts, 131, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 128, 47)) +>t03 : Symbol(t03, Decl(genericDefaults.ts, 126, 37)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(a, Decl(genericDefaults.ts, 128, 47)) + +const t03c03 = (>x).a; +>t03c03 : Symbol(t03c03, Decl(genericDefaults.ts, 132, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 128, 47)) +>t03 : Symbol(t03, Decl(genericDefaults.ts, 126, 37)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(a, Decl(genericDefaults.ts, 128, 47)) + +const t03c04 = (>x).a; +>t03c04 : Symbol(t03c04, Decl(genericDefaults.ts, 133, 5)) +>(>x).a : Symbol(a, Decl(genericDefaults.ts, 128, 47)) +>t03 : Symbol(t03, Decl(genericDefaults.ts, 126, 37)) +>x : Symbol(x, Decl(genericDefaults.ts, 0, 13)) +>a : Symbol(a, Decl(genericDefaults.ts, 128, 47)) + diff --git a/tests/baselines/reference/genericDefaults.types b/tests/baselines/reference/genericDefaults.types index 4977d2d8896..2f12a8e90fd 100644 --- a/tests/baselines/reference/genericDefaults.types +++ b/tests/baselines/reference/genericDefaults.types @@ -655,3 +655,163 @@ const Derived02c03 = new Derived02(1); >Derived02 : typeof Derived02 >1 : 1 +type t00 = { a: T; } +>t00 : t00 +>T : T +>a : T +>T : T + +const t00c00 = (x).a; +>t00c00 : number +>(x).a : number +>(x) : t00 +>x : t00 +>t00 : t00 +>x : any +>a : number + +const t00c01 = (>x).a; +>t00c01 : number +>(>x).a : number +>(>x) : t00 +>>x : t00 +>t00 : t00 +>x : any +>a : number + +type t01 = { a: [T, U]; } +>t01 : t01 +>T : T +>U : U +>T : T +>a : [T, U] +>T : T +>U : U + +const t01c00 = (>x).a; +>t01c00 : [number, number] +>(>x).a : [number, number] +>(>x) : t01 +>>x : t01 +>t01 : t01 +>x : any +>a : [number, number] + +const t01c01 = (>x).a; +>t01c01 : [number, string] +>(>x).a : [number, string] +>(>x) : t01 +>>x : t01 +>t01 : t01 +>x : any +>a : [number, string] + +type t02 = { a: [T, U]; } +>t02 : t02 +>T : T +>U : U +>T : T +>a : [T, U] +>T : T +>U : U + +const t02c00 = (>x).a; +>t02c00 : [number, number] +>(>x).a : [number, number] +>(>x) : t02 +>>x : t02 +>t02 : t02 +>x : any +>a : [number, number] + +const t02c01 = (>x).a; +>t02c01 : [1, 1] +>(>x).a : [1, 1] +>(>x) : t02<1, 1> +>>x : t02<1, 1> +>t02 : t02 +>x : any +>a : [1, 1] + +const t02c02 = (>x).a; +>t02c02 : [number, number] +>(>x).a : [number, number] +>(>x) : t02 +>>x : t02 +>t02 : t02 +>x : any +>a : [number, number] + +const t02c03 = (>x).a; +>t02c03 : [1, number] +>(>x).a : [1, number] +>(>x) : t02<1, number> +>>x : t02<1, number> +>t02 : t02 +>x : any +>a : [1, number] + +const t02c04 = (>x).a; +>t02c04 : [number, 1] +>(>x).a : [number, 1] +>(>x) : t02 +>>x : t02 +>t02 : t02 +>x : any +>a : [number, 1] + +type t03 = { a: [T, U]; } +>t03 : t03 +>T : T +>U : U +>T : T +>T : T +>a : [T, U] +>T : T +>U : U + +const t03c00 = (>x).a; +>t03c00 : [number, number] +>(>x).a : [number, number] +>(>x) : t03 +>>x : t03 +>t03 : t03 +>x : any +>a : [number, number] + +const t03c01 = (>x).a; +>t03c01 : [1, 1] +>(>x).a : [1, 1] +>(>x) : t03<1, 1> +>>x : t03<1, 1> +>t03 : t03 +>x : any +>a : [1, 1] + +const t03c02 = (>x).a; +>t03c02 : [number, number] +>(>x).a : [number, number] +>(>x) : t03 +>>x : t03 +>t03 : t03 +>x : any +>a : [number, number] + +const t03c03 = (>x).a; +>t03c03 : [1, 1] +>(>x).a : [1, 1] +>(>x) : t03<1, 1> +>>x : t03<1, 1> +>t03 : t03 +>x : any +>a : [1, 1] + +const t03c04 = (>x).a; +>t03c04 : [number, 1] +>(>x).a : [number, 1] +>(>x) : t03 +>>x : t03 +>t03 : t03 +>x : any +>a : [number, 1] + diff --git a/tests/baselines/reference/genericDefaultsErrors.errors.txt b/tests/baselines/reference/genericDefaultsErrors.errors.txt index ad2e4068590..94945b2b9c5 100644 --- a/tests/baselines/reference/genericDefaultsErrors.errors.txt +++ b/tests/baselines/reference/genericDefaultsErrors.errors.txt @@ -32,7 +32,7 @@ tests/cases/compiler/genericDefaultsErrors.ts(39,32): error TS2344: Type 'number tests/cases/compiler/genericDefaultsErrors.ts(42,15): error TS2707: Generic type 'i09' requires between 2 and 3 type arguments. tests/cases/compiler/genericDefaultsErrors.ts(43,15): error TS2707: Generic type 'i09' requires between 2 and 3 type arguments. tests/cases/compiler/genericDefaultsErrors.ts(46,15): error TS2707: Generic type 'i09' requires between 2 and 3 type arguments. -tests/cases/compiler/genericDefaultsErrors.ts(48,17): error TS2367: Type parameter 'T' cannot be referenced outside of a declaration that defines it. +tests/cases/compiler/genericDefaultsErrors.ts(48,20): error TS2367: Type parameter 'T' cannot be referenced outside of the declaration that defines it. ==== tests/cases/compiler/genericDefaultsErrors.ts (33 errors) ==== @@ -150,6 +150,6 @@ tests/cases/compiler/genericDefaultsErrors.ts(48,17): error TS2367: Type paramet !!! error TS2707: Generic type 'i09' requires between 2 and 3 type arguments. interface i10 { x: T; } // error - ~ -!!! error TS2367: Type parameter 'T' cannot be referenced outside of a declaration that defines it. + ~ +!!! error TS2367: Type parameter 'T' cannot be referenced outside of the declaration that defines it. interface i10 {} \ No newline at end of file diff --git a/tests/cases/compiler/genericDefaults.ts b/tests/cases/compiler/genericDefaults.ts index df507a32a91..1fc09639894 100644 --- a/tests/cases/compiler/genericDefaults.ts +++ b/tests/cases/compiler/genericDefaults.ts @@ -111,3 +111,25 @@ const Derived02c00 = new Derived02(); const Derived02c01 = new Derived02(1); const Derived02c02 = new Derived02(); const Derived02c03 = new Derived02(1); + +type t00 = { a: T; } +const t00c00 = (x).a; +const t00c01 = (>x).a; + +type t01 = { a: [T, U]; } +const t01c00 = (>x).a; +const t01c01 = (>x).a; + +type t02 = { a: [T, U]; } +const t02c00 = (>x).a; +const t02c01 = (>x).a; +const t02c02 = (>x).a; +const t02c03 = (>x).a; +const t02c04 = (>x).a; + +type t03 = { a: [T, U]; } +const t03c00 = (>x).a; +const t03c01 = (>x).a; +const t03c02 = (>x).a; +const t03c03 = (>x).a; +const t03c04 = (>x).a;