add strictTuples flag giving tuples known length

This commit is contained in:
Tycho Grouwstra
2017-08-20 02:54:26 +08:00
parent d03d1074ee
commit 1f77317b64
27 changed files with 185 additions and 69 deletions
+7
View File
@@ -64,6 +64,7 @@ namespace ts {
const noUnusedIdentifiers = !!compilerOptions.noUnusedLocals || !!compilerOptions.noUnusedParameters;
const allowSyntheticDefaultImports = typeof compilerOptions.allowSyntheticDefaultImports !== "undefined" ? compilerOptions.allowSyntheticDefaultImports : modulekind === ModuleKind.System;
const strictNullChecks = compilerOptions.strictNullChecks === undefined ? compilerOptions.strict : compilerOptions.strictNullChecks;
const strictTuples = compilerOptions.strictTuples === undefined ? compilerOptions.strict : compilerOptions.strictTuples;
const noImplicitAny = compilerOptions.noImplicitAny === undefined ? compilerOptions.strict : compilerOptions.noImplicitAny;
const noImplicitThis = compilerOptions.noImplicitThis === undefined ? compilerOptions.strict : compilerOptions.noImplicitThis;
@@ -7161,6 +7162,12 @@ namespace ts {
property.type = typeParameter;
properties.push(property);
}
if (strictTuples) {
const lengthSymbol = createSymbol(SymbolFlags.Property, "length" as __String);
lengthSymbol.type = getLiteralType(arity);
lengthSymbol.checkFlags = CheckFlags.Readonly;
properties.push(lengthSymbol);
}
const type = <GenericType & InterfaceTypeWithDeclaredMembers>createObjectType(ObjectFlags.Tuple | ObjectFlags.Reference);
type.typeParameters = typeParameters;
type.outerTypeParameters = undefined;
+7
View File
@@ -269,6 +269,13 @@ namespace ts {
category: Diagnostics.Strict_Type_Checking_Options,
description: Diagnostics.Enable_strict_null_checks
},
{
name: "strictTuples",
type: "boolean",
showInSimplifiedHelpView: true,
category: Diagnostics.Strict_Type_Checking_Options,
description: Diagnostics.Enable_strict_tuple_checks
},
{
name: "noImplicitThis",
type: "boolean",
+4
View File
@@ -3302,6 +3302,10 @@
"category": "Message",
"code": 6185
},
"Enable strict tuple checks.": {
"category": "Message",
"code": 6187
},
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",
"code": 7005
+1
View File
@@ -3622,6 +3622,7 @@ namespace ts {
sourceRoot?: string;
strict?: boolean;
strictNullChecks?: boolean; // Always combine with strict property
strictTuples?: boolean;
/* @internal */ stripInternal?: boolean;
suppressExcessPropertyErrors?: boolean;
suppressImplicitAnyIndexErrors?: boolean;
@@ -16,6 +16,12 @@ namespace ts {
strictNullChecks: false
}
},
"/dev/tsconfig.strictTuples.json": {
extends: "./tsconfig",
compilerOptions: {
strictTuples: false
}
},
"/dev/configs/base.json": {
compilerOptions: {
allowJs: true,
+4
View File
@@ -413,6 +413,10 @@ var x = 0;`, {
options: { compilerOptions: { strictNullChecks: true }, fileName: "input.js", reportDiagnostics: true }
});
transpilesCorrectly("Supports setting 'strictTuples'", "x;", {
options: { compilerOptions: { strictTuples: true }, fileName: "input.js", reportDiagnostics: true }
});
transpilesCorrectly("Supports setting 'stripInternal'", "x;", {
options: { compilerOptions: { stripInternal: true }, fileName: "input.js", reportDiagnostics: true }
});
+1
View File
@@ -2448,6 +2448,7 @@ namespace ts.server.protocol {
sourceRoot?: string;
strict?: boolean;
strictNullChecks?: boolean;
strictTuples?: boolean;
suppressExcessPropertyErrors?: boolean;
suppressImplicitAnyIndexErrors?: boolean;
target?: ScriptTarget | ts.ScriptTarget;
@@ -40,12 +40,12 @@ type Strange<T> = string; // Type parameter not used
var s: Strange<number>;
s = "hello";
interface Tuple<A, B> {
interface AB<A, B> {
a: A;
b: B;
}
type Pair<T> = Tuple<T, T>;
type Pair<T> = AB<T, T>;
interface TaggedPair<T> extends Pair<T> {
tag: string;
@@ -124,29 +124,29 @@ var s: Strange<number>;
s = "hello";
>s : Symbol(s, Decl(genericTypeAliases.ts, 38, 3))
interface Tuple<A, B> {
>Tuple : Symbol(Tuple, Decl(genericTypeAliases.ts, 39, 12))
>A : Symbol(A, Decl(genericTypeAliases.ts, 41, 16))
>B : Symbol(B, Decl(genericTypeAliases.ts, 41, 18))
interface AB<A, B> {
>AB : Symbol(AB, Decl(genericTypeAliases.ts, 39, 12))
>A : Symbol(A, Decl(genericTypeAliases.ts, 41, 13))
>B : Symbol(B, Decl(genericTypeAliases.ts, 41, 15))
a: A;
>a : Symbol(Tuple.a, Decl(genericTypeAliases.ts, 41, 23))
>A : Symbol(A, Decl(genericTypeAliases.ts, 41, 16))
>a : Symbol(AB.a, Decl(genericTypeAliases.ts, 41, 20))
>A : Symbol(A, Decl(genericTypeAliases.ts, 41, 13))
b: B;
>b : Symbol(Tuple.b, Decl(genericTypeAliases.ts, 42, 9))
>B : Symbol(B, Decl(genericTypeAliases.ts, 41, 18))
>b : Symbol(AB.b, Decl(genericTypeAliases.ts, 42, 9))
>B : Symbol(B, Decl(genericTypeAliases.ts, 41, 15))
}
type Pair<T> = Tuple<T, T>;
type Pair<T> = AB<T, T>;
>Pair : Symbol(Pair, Decl(genericTypeAliases.ts, 44, 1))
>T : Symbol(T, Decl(genericTypeAliases.ts, 46, 10))
>Tuple : Symbol(Tuple, Decl(genericTypeAliases.ts, 39, 12))
>AB : Symbol(AB, Decl(genericTypeAliases.ts, 39, 12))
>T : Symbol(T, Decl(genericTypeAliases.ts, 46, 10))
>T : Symbol(T, Decl(genericTypeAliases.ts, 46, 10))
interface TaggedPair<T> extends Pair<T> {
>TaggedPair : Symbol(TaggedPair, Decl(genericTypeAliases.ts, 46, 27))
>TaggedPair : Symbol(TaggedPair, Decl(genericTypeAliases.ts, 46, 24))
>T : Symbol(T, Decl(genericTypeAliases.ts, 48, 21))
>Pair : Symbol(Pair, Decl(genericTypeAliases.ts, 44, 1))
>T : Symbol(T, Decl(genericTypeAliases.ts, 48, 21))
@@ -157,17 +157,17 @@ interface TaggedPair<T> extends Pair<T> {
var p: TaggedPair<number>;
>p : Symbol(p, Decl(genericTypeAliases.ts, 52, 3))
>TaggedPair : Symbol(TaggedPair, Decl(genericTypeAliases.ts, 46, 27))
>TaggedPair : Symbol(TaggedPair, Decl(genericTypeAliases.ts, 46, 24))
p.a = 1;
>p.a : Symbol(Tuple.a, Decl(genericTypeAliases.ts, 41, 23))
>p.a : Symbol(AB.a, Decl(genericTypeAliases.ts, 41, 20))
>p : Symbol(p, Decl(genericTypeAliases.ts, 52, 3))
>a : Symbol(Tuple.a, Decl(genericTypeAliases.ts, 41, 23))
>a : Symbol(AB.a, Decl(genericTypeAliases.ts, 41, 20))
p.b = 2;
>p.b : Symbol(Tuple.b, Decl(genericTypeAliases.ts, 42, 9))
>p.b : Symbol(AB.b, Decl(genericTypeAliases.ts, 42, 9))
>p : Symbol(p, Decl(genericTypeAliases.ts, 52, 3))
>b : Symbol(Tuple.b, Decl(genericTypeAliases.ts, 42, 9))
>b : Symbol(AB.b, Decl(genericTypeAliases.ts, 42, 9))
p.tag = "test";
>p.tag : Symbol(TaggedPair.tag, Decl(genericTypeAliases.ts, 48, 41))
@@ -158,8 +158,8 @@ s = "hello";
>s : string
>"hello" : "hello"
interface Tuple<A, B> {
>Tuple : Tuple<A, B>
interface AB<A, B> {
>AB : AB<A, B>
>A : A
>B : B
@@ -172,17 +172,17 @@ interface Tuple<A, B> {
>B : B
}
type Pair<T> = Tuple<T, T>;
>Pair : Tuple<T, T>
type Pair<T> = AB<T, T>;
>Pair : AB<T, T>
>T : T
>Tuple : Tuple<A, B>
>AB : AB<A, B>
>T : T
>T : T
interface TaggedPair<T> extends Pair<T> {
>TaggedPair : TaggedPair<T>
>T : T
>Pair : Tuple<T, T>
>Pair : AB<T, T>
>T : T
tag: string;
@@ -1,20 +1,20 @@
//// [nominalSubtypeCheckOfTypeParameter.ts]
interface Tuple<T, S> {
interface BinaryTuple<T, S> {
first: T
second: S
second: S
}
interface Sequence<T> {
hasNext(): boolean
pop(): T
zip<S>(seq: Sequence<S>): Sequence<Tuple<T, S>>
pop(): T
zip<S>(seq: Sequence<S>): Sequence<BinaryTuple<T, S>>
}
// error, despite the fact that the code explicitly says List<T> extends Sequence<T>, the current rules for infinitely expanding type references
// perform nominal subtyping checks that allow variance for type arguments, but not nominal subtyping for the generic type itself
interface List<T> extends Sequence<T> {
getLength(): number
zip<S>(seq: Sequence<S>): List<Tuple<T, S>>
zip<S>(seq: Sequence<S>): List<BinaryTuple<T, S>>
}
@@ -1,16 +1,16 @@
=== tests/cases/conformance/types/typeRelationships/recursiveTypes/nominalSubtypeCheckOfTypeParameter.ts ===
interface Tuple<T, S> {
>Tuple : Symbol(Tuple, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 0))
>T : Symbol(T, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 16))
>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 18))
interface BinaryTuple<T, S> {
>BinaryTuple : Symbol(BinaryTuple, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 0))
>T : Symbol(T, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 22))
>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 24))
first: T
>first : Symbol(Tuple.first, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 23))
>T : Symbol(T, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 16))
>first : Symbol(BinaryTuple.first, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 29))
>T : Symbol(T, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 22))
second: S
>second : Symbol(Tuple.second, Decl(nominalSubtypeCheckOfTypeParameter.ts, 1, 12))
>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 18))
second: S
>second : Symbol(BinaryTuple.second, Decl(nominalSubtypeCheckOfTypeParameter.ts, 1, 12))
>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 24))
}
interface Sequence<T> {
@@ -20,20 +20,20 @@ interface Sequence<T> {
hasNext(): boolean
>hasNext : Symbol(Sequence.hasNext, Decl(nominalSubtypeCheckOfTypeParameter.ts, 5, 23))
pop(): T
pop(): T
>pop : Symbol(Sequence.pop, Decl(nominalSubtypeCheckOfTypeParameter.ts, 6, 22))
>T : Symbol(T, Decl(nominalSubtypeCheckOfTypeParameter.ts, 5, 19))
zip<S>(seq: Sequence<S>): Sequence<Tuple<T, S>>
>zip : Symbol(Sequence.zip, Decl(nominalSubtypeCheckOfTypeParameter.ts, 7, 14))
>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 8, 10))
>seq : Symbol(seq, Decl(nominalSubtypeCheckOfTypeParameter.ts, 8, 13))
zip<S>(seq: Sequence<S>): Sequence<BinaryTuple<T, S>>
>zip : Symbol(Sequence.zip, Decl(nominalSubtypeCheckOfTypeParameter.ts, 7, 12))
>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 8, 8))
>seq : Symbol(seq, Decl(nominalSubtypeCheckOfTypeParameter.ts, 8, 11))
>Sequence : Symbol(Sequence, Decl(nominalSubtypeCheckOfTypeParameter.ts, 3, 1))
>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 8, 10))
>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 8, 8))
>Sequence : Symbol(Sequence, Decl(nominalSubtypeCheckOfTypeParameter.ts, 3, 1))
>Tuple : Symbol(Tuple, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 0))
>BinaryTuple : Symbol(BinaryTuple, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 0))
>T : Symbol(T, Decl(nominalSubtypeCheckOfTypeParameter.ts, 5, 19))
>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 8, 10))
>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 8, 8))
}
// error, despite the fact that the code explicitly says List<T> extends Sequence<T>, the current rules for infinitely expanding type references
@@ -47,15 +47,15 @@ interface List<T> extends Sequence<T> {
getLength(): number
>getLength : Symbol(List.getLength, Decl(nominalSubtypeCheckOfTypeParameter.ts, 13, 39))
zip<S>(seq: Sequence<S>): List<Tuple<T, S>>
zip<S>(seq: Sequence<S>): List<BinaryTuple<T, S>>
>zip : Symbol(List.zip, Decl(nominalSubtypeCheckOfTypeParameter.ts, 14, 23))
>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 15, 10))
>seq : Symbol(seq, Decl(nominalSubtypeCheckOfTypeParameter.ts, 15, 13))
>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 15, 8))
>seq : Symbol(seq, Decl(nominalSubtypeCheckOfTypeParameter.ts, 15, 11))
>Sequence : Symbol(Sequence, Decl(nominalSubtypeCheckOfTypeParameter.ts, 3, 1))
>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 15, 10))
>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 15, 8))
>List : Symbol(List, Decl(nominalSubtypeCheckOfTypeParameter.ts, 9, 1))
>Tuple : Symbol(Tuple, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 0))
>BinaryTuple : Symbol(BinaryTuple, Decl(nominalSubtypeCheckOfTypeParameter.ts, 0, 0))
>T : Symbol(T, Decl(nominalSubtypeCheckOfTypeParameter.ts, 13, 15))
>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 15, 10))
>S : Symbol(S, Decl(nominalSubtypeCheckOfTypeParameter.ts, 15, 8))
}
@@ -1,6 +1,6 @@
=== tests/cases/conformance/types/typeRelationships/recursiveTypes/nominalSubtypeCheckOfTypeParameter.ts ===
interface Tuple<T, S> {
>Tuple : Tuple<T, S>
interface BinaryTuple<T, S> {
>BinaryTuple : BinaryTuple<T, S>
>T : T
>S : S
@@ -8,7 +8,7 @@ interface Tuple<T, S> {
>first : T
>T : T
second: S
second: S
>second : S
>S : S
}
@@ -20,18 +20,18 @@ interface Sequence<T> {
hasNext(): boolean
>hasNext : () => boolean
pop(): T
pop(): T
>pop : () => T
>T : T
zip<S>(seq: Sequence<S>): Sequence<Tuple<T, S>>
>zip : <S>(seq: Sequence<S>) => Sequence<Tuple<T, S>>
zip<S>(seq: Sequence<S>): Sequence<BinaryTuple<T, S>>
>zip : <S>(seq: Sequence<S>) => Sequence<BinaryTuple<T, S>>
>S : S
>seq : Sequence<S>
>Sequence : Sequence<T>
>S : S
>Sequence : Sequence<T>
>Tuple : Tuple<T, S>
>BinaryTuple : BinaryTuple<T, S>
>T : T
>S : S
}
@@ -47,14 +47,14 @@ interface List<T> extends Sequence<T> {
getLength(): number
>getLength : () => number
zip<S>(seq: Sequence<S>): List<Tuple<T, S>>
>zip : <S>(seq: Sequence<S>) => List<Tuple<T, S>>
zip<S>(seq: Sequence<S>): List<BinaryTuple<T, S>>
>zip : <S>(seq: Sequence<S>) => List<BinaryTuple<T, S>>
>S : S
>seq : Sequence<S>
>Sequence : Sequence<T>
>S : S
>List : List<T>
>Tuple : Tuple<T, S>
>BinaryTuple : BinaryTuple<T, S>
>T : T
>S : S
}
@@ -0,0 +1,2 @@
x;
//# sourceMappingURL=input.js.map
@@ -22,6 +22,7 @@
"strict": true /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictTuples": true, /* Enable strict tuple checks. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
@@ -22,6 +22,7 @@
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictTuples": true, /* Enable strict tuple checks. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
@@ -22,6 +22,7 @@
"strict": true /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictTuples": true, /* Enable strict tuple checks. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
@@ -22,6 +22,7 @@
"strict": true /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictTuples": true, /* Enable strict tuple checks. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
@@ -22,6 +22,7 @@
"strict": true /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictTuples": true, /* Enable strict tuple checks. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
@@ -22,6 +22,7 @@
"strict": true /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictTuples": true, /* Enable strict tuple checks. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
@@ -22,6 +22,7 @@
"strict": true /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictTuples": true, /* Enable strict tuple checks. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
@@ -22,6 +22,7 @@
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
// "strictNullChecks": true, /* Enable strict null checks. */
// "strictTuples": true, /* Enable strict tuple checks. */
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
@@ -0,0 +1,26 @@
tests/cases/compiler/tupleLength.ts(11,5): error TS2403: Subsequent variable declarations must have the same type. Variable 't1' must be of type '[number]', but here has type '[number, number]'.
tests/cases/compiler/tupleLength.ts(12,5): error TS2403: Subsequent variable declarations must have the same type. Variable 't2' must be of type '[number, number]', but here has type '[number]'.
==== tests/cases/compiler/tupleLength.ts (2 errors) ====
// var t0: [];
var t1: [number];
var t2: [number, number];
var arr: number[];
// var len0: 0 = t0.length;
var len1: 1 = t1.length;
var len2: 2 = t2.length;
var lena: number = arr.length;
var t1 = t2; // error
~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 't1' must be of type '[number]', but here has type '[number, number]'.
var t2 = t1; // error
~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 't2' must be of type '[number, number]', but here has type '[number]'.
type A<T extends any[]> = T['length'];
var b: A<[boolean]>;
var c: 1 = b;
+32
View File
@@ -0,0 +1,32 @@
//// [tupleLength.ts]
// var t0: [];
var t1: [number];
var t2: [number, number];
var arr: number[];
// var len0: 0 = t0.length;
var len1: 1 = t1.length;
var len2: 2 = t2.length;
var lena: number = arr.length;
var t1 = t2; // error
var t2 = t1; // error
type A<T extends any[]> = T['length'];
var b: A<[boolean]>;
var c: 1 = b;
//// [tupleLength.js]
// var t0: [];
var t1;
var t2;
var arr;
// var len0: 0 = t0.length;
var len1 = t1.length;
var len2 = t2.length;
var lena = arr.length;
var t1 = t2; // error
var t2 = t1; // error
var b;
var c = b;
+18
View File
@@ -0,0 +1,18 @@
// @strictTuples: true
// var t0: [];
var t1: [number];
var t2: [number, number];
var arr: number[];
// var len0: 0 = t0.length;
var len1: 1 = t1.length;
var len2: 2 = t2.length;
var lena: number = arr.length;
var t1 = t2; // error
var t2 = t1; // error
type A<T extends any[]> = T['length'];
var b: A<[boolean]>;
var c: 1 = b;
@@ -39,12 +39,12 @@ type Strange<T> = string; // Type parameter not used
var s: Strange<number>;
s = "hello";
interface Tuple<A, B> {
interface AB<A, B> {
a: A;
b: B;
}
type Pair<T> = Tuple<T, T>;
type Pair<T> = AB<T, T>;
interface TaggedPair<T> extends Pair<T> {
tag: string;
@@ -1,17 +1,17 @@
interface Tuple<T, S> {
interface BinaryTuple<T, S> {
first: T
second: S
second: S
}
interface Sequence<T> {
hasNext(): boolean
pop(): T
zip<S>(seq: Sequence<S>): Sequence<Tuple<T, S>>
pop(): T
zip<S>(seq: Sequence<S>): Sequence<BinaryTuple<T, S>>
}
// error, despite the fact that the code explicitly says List<T> extends Sequence<T>, the current rules for infinitely expanding type references
// perform nominal subtyping checks that allow variance for type arguments, but not nominal subtyping for the generic type itself
interface List<T> extends Sequence<T> {
getLength(): number
zip<S>(seq: Sequence<S>): List<Tuple<T, S>>
zip<S>(seq: Sequence<S>): List<BinaryTuple<T, S>>
}