From f37fc1d42ef7805ba029bbca201299863d49c050 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Thu, 9 Jul 2015 11:31:08 -0700 Subject: [PATCH 1/3] Infer types to statics in a class expression --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1b34952f3ae..6c0b74c0b48 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5491,7 +5491,7 @@ namespace ts { } } else if (source.flags & TypeFlags.ObjectType && (target.flags & (TypeFlags.Reference | TypeFlags.Tuple) || - (target.flags & TypeFlags.Anonymous) && target.symbol && target.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral))) { + (target.flags & TypeFlags.Anonymous) && target.symbol && target.symbol.flags & (SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class))) { // If source is an object type, and target is a type reference, a tuple type, the type of a method, or a type literal, infer from members if (isInProcess(source, target)) { return; From f56298a0cd231905172fcdeb7bc62f16c8632ed2 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Thu, 9 Jul 2015 11:31:24 -0700 Subject: [PATCH 2/3] Add a test --- ...ypeArgumentInferenceWithClassExpression.js | 22 ++++++++++++++++++ ...gumentInferenceWithClassExpression.symbols | 19 +++++++++++++++ ...ArgumentInferenceWithClassExpression.types | 23 +++++++++++++++++++ ...ypeArgumentInferenceWithClassExpression.ts | 5 ++++ 4 files changed, 69 insertions(+) create mode 100644 tests/baselines/reference/typeArgumentInferenceWithClassExpression.js create mode 100644 tests/baselines/reference/typeArgumentInferenceWithClassExpression.symbols create mode 100644 tests/baselines/reference/typeArgumentInferenceWithClassExpression.types create mode 100644 tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression.ts diff --git a/tests/baselines/reference/typeArgumentInferenceWithClassExpression.js b/tests/baselines/reference/typeArgumentInferenceWithClassExpression.js new file mode 100644 index 00000000000..cc0bf971473 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceWithClassExpression.js @@ -0,0 +1,22 @@ +//// [typeArgumentInferenceWithClassExpression.ts] +function foo(x = class { static prop: T }): T { + return undefined; +} + +foo(class { static prop = "hello" }).length; + +//// [typeArgumentInferenceWithClassExpression.js] +function foo(x) { + if (x === void 0) { x = (function () { + function class_1() { + } + return class_1; + })(); } + return undefined; +} +foo((function () { + function class_2() { + } + class_2.prop = "hello"; + return class_2; +})()).length; diff --git a/tests/baselines/reference/typeArgumentInferenceWithClassExpression.symbols b/tests/baselines/reference/typeArgumentInferenceWithClassExpression.symbols new file mode 100644 index 00000000000..dac982595cb --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceWithClassExpression.symbols @@ -0,0 +1,19 @@ +=== tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression.ts === +function foo(x = class { static prop: T }): T { +>foo : Symbol(foo, Decl(typeArgumentInferenceWithClassExpression.ts, 0, 0)) +>T : Symbol(T, Decl(typeArgumentInferenceWithClassExpression.ts, 0, 13)) +>x : Symbol(x, Decl(typeArgumentInferenceWithClassExpression.ts, 0, 16)) +>prop : Symbol((Anonymous class).prop, Decl(typeArgumentInferenceWithClassExpression.ts, 0, 27)) +>T : Symbol(T, Decl(typeArgumentInferenceWithClassExpression.ts, 0, 13)) +>T : Symbol(T, Decl(typeArgumentInferenceWithClassExpression.ts, 0, 13)) + + return undefined; +>undefined : Symbol(undefined) +} + +foo(class { static prop = "hello" }).length; +>foo(class { static prop = "hello" }).length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) +>foo : Symbol(foo, Decl(typeArgumentInferenceWithClassExpression.ts, 0, 0)) +>prop : Symbol((Anonymous class).prop, Decl(typeArgumentInferenceWithClassExpression.ts, 4, 11)) +>length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) + diff --git a/tests/baselines/reference/typeArgumentInferenceWithClassExpression.types b/tests/baselines/reference/typeArgumentInferenceWithClassExpression.types new file mode 100644 index 00000000000..3eab8a4ab62 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceWithClassExpression.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression.ts === +function foo(x = class { static prop: T }): T { +>foo : (x?: typeof (Anonymous class)) => T +>T : T +>x : typeof (Anonymous class) +>class { static prop: T } : typeof (Anonymous class) +>prop : T +>T : T +>T : T + + return undefined; +>undefined : undefined +} + +foo(class { static prop = "hello" }).length; +>foo(class { static prop = "hello" }).length : number +>foo(class { static prop = "hello" }) : string +>foo : (x?: typeof (Anonymous class)) => T +>class { static prop = "hello" } : typeof (Anonymous class) +>prop : string +>"hello" : string +>length : number + diff --git a/tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression.ts b/tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression.ts new file mode 100644 index 00000000000..21ca07ea2a2 --- /dev/null +++ b/tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression.ts @@ -0,0 +1,5 @@ +function foo(x = class { static prop: T }): T { + return undefined; +} + +foo(class { static prop = "hello" }).length; \ No newline at end of file From 8bb956eb917c07058773b01d77c7e586b7fa8571 Mon Sep 17 00:00:00 2001 From: Jason Freeman Date: Thu, 9 Jul 2015 14:41:08 -0700 Subject: [PATCH 3/3] More tests --- ...eArgumentInferenceWithClassExpression1.js} | 4 ++-- ...mentInferenceWithClassExpression1.symbols} | 18 +++++++------- ...gumentInferenceWithClassExpression1.types} | 2 +- ...ntInferenceWithClassExpression2.errors.txt | 16 +++++++++++++ ...peArgumentInferenceWithClassExpression2.js | 24 +++++++++++++++++++ ...peArgumentInferenceWithClassExpression3.js | 22 +++++++++++++++++ ...umentInferenceWithClassExpression3.symbols | 19 +++++++++++++++ ...rgumentInferenceWithClassExpression3.types | 23 ++++++++++++++++++ ...eArgumentInferenceWithClassExpression1.ts} | 0 ...peArgumentInferenceWithClassExpression2.ts | 6 +++++ ...peArgumentInferenceWithClassExpression3.ts | 5 ++++ 11 files changed, 127 insertions(+), 12 deletions(-) rename tests/baselines/reference/{typeArgumentInferenceWithClassExpression.js => typeArgumentInferenceWithClassExpression1.js} (76%) rename tests/baselines/reference/{typeArgumentInferenceWithClassExpression.symbols => typeArgumentInferenceWithClassExpression1.symbols} (58%) rename tests/baselines/reference/{typeArgumentInferenceWithClassExpression.types => typeArgumentInferenceWithClassExpression1.types} (91%) create mode 100644 tests/baselines/reference/typeArgumentInferenceWithClassExpression2.errors.txt create mode 100644 tests/baselines/reference/typeArgumentInferenceWithClassExpression2.js create mode 100644 tests/baselines/reference/typeArgumentInferenceWithClassExpression3.js create mode 100644 tests/baselines/reference/typeArgumentInferenceWithClassExpression3.symbols create mode 100644 tests/baselines/reference/typeArgumentInferenceWithClassExpression3.types rename tests/cases/conformance/es6/classExpressions/{typeArgumentInferenceWithClassExpression.ts => typeArgumentInferenceWithClassExpression1.ts} (100%) create mode 100644 tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression2.ts create mode 100644 tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression3.ts diff --git a/tests/baselines/reference/typeArgumentInferenceWithClassExpression.js b/tests/baselines/reference/typeArgumentInferenceWithClassExpression1.js similarity index 76% rename from tests/baselines/reference/typeArgumentInferenceWithClassExpression.js rename to tests/baselines/reference/typeArgumentInferenceWithClassExpression1.js index cc0bf971473..25ce3743fa2 100644 --- a/tests/baselines/reference/typeArgumentInferenceWithClassExpression.js +++ b/tests/baselines/reference/typeArgumentInferenceWithClassExpression1.js @@ -1,11 +1,11 @@ -//// [typeArgumentInferenceWithClassExpression.ts] +//// [typeArgumentInferenceWithClassExpression1.ts] function foo(x = class { static prop: T }): T { return undefined; } foo(class { static prop = "hello" }).length; -//// [typeArgumentInferenceWithClassExpression.js] +//// [typeArgumentInferenceWithClassExpression1.js] function foo(x) { if (x === void 0) { x = (function () { function class_1() { diff --git a/tests/baselines/reference/typeArgumentInferenceWithClassExpression.symbols b/tests/baselines/reference/typeArgumentInferenceWithClassExpression1.symbols similarity index 58% rename from tests/baselines/reference/typeArgumentInferenceWithClassExpression.symbols rename to tests/baselines/reference/typeArgumentInferenceWithClassExpression1.symbols index dac982595cb..ceb97a73af8 100644 --- a/tests/baselines/reference/typeArgumentInferenceWithClassExpression.symbols +++ b/tests/baselines/reference/typeArgumentInferenceWithClassExpression1.symbols @@ -1,11 +1,11 @@ -=== tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression.ts === +=== tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression1.ts === function foo(x = class { static prop: T }): T { ->foo : Symbol(foo, Decl(typeArgumentInferenceWithClassExpression.ts, 0, 0)) ->T : Symbol(T, Decl(typeArgumentInferenceWithClassExpression.ts, 0, 13)) ->x : Symbol(x, Decl(typeArgumentInferenceWithClassExpression.ts, 0, 16)) ->prop : Symbol((Anonymous class).prop, Decl(typeArgumentInferenceWithClassExpression.ts, 0, 27)) ->T : Symbol(T, Decl(typeArgumentInferenceWithClassExpression.ts, 0, 13)) ->T : Symbol(T, Decl(typeArgumentInferenceWithClassExpression.ts, 0, 13)) +>foo : Symbol(foo, Decl(typeArgumentInferenceWithClassExpression1.ts, 0, 0)) +>T : Symbol(T, Decl(typeArgumentInferenceWithClassExpression1.ts, 0, 13)) +>x : Symbol(x, Decl(typeArgumentInferenceWithClassExpression1.ts, 0, 16)) +>prop : Symbol((Anonymous class).prop, Decl(typeArgumentInferenceWithClassExpression1.ts, 0, 27)) +>T : Symbol(T, Decl(typeArgumentInferenceWithClassExpression1.ts, 0, 13)) +>T : Symbol(T, Decl(typeArgumentInferenceWithClassExpression1.ts, 0, 13)) return undefined; >undefined : Symbol(undefined) @@ -13,7 +13,7 @@ function foo(x = class { static prop: T }): T { foo(class { static prop = "hello" }).length; >foo(class { static prop = "hello" }).length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) ->foo : Symbol(foo, Decl(typeArgumentInferenceWithClassExpression.ts, 0, 0)) ->prop : Symbol((Anonymous class).prop, Decl(typeArgumentInferenceWithClassExpression.ts, 4, 11)) +>foo : Symbol(foo, Decl(typeArgumentInferenceWithClassExpression1.ts, 0, 0)) +>prop : Symbol((Anonymous class).prop, Decl(typeArgumentInferenceWithClassExpression1.ts, 4, 11)) >length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) diff --git a/tests/baselines/reference/typeArgumentInferenceWithClassExpression.types b/tests/baselines/reference/typeArgumentInferenceWithClassExpression1.types similarity index 91% rename from tests/baselines/reference/typeArgumentInferenceWithClassExpression.types rename to tests/baselines/reference/typeArgumentInferenceWithClassExpression1.types index 3eab8a4ab62..63ee1309383 100644 --- a/tests/baselines/reference/typeArgumentInferenceWithClassExpression.types +++ b/tests/baselines/reference/typeArgumentInferenceWithClassExpression1.types @@ -1,4 +1,4 @@ -=== tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression.ts === +=== tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression1.ts === function foo(x = class { static prop: T }): T { >foo : (x?: typeof (Anonymous class)) => T >T : T diff --git a/tests/baselines/reference/typeArgumentInferenceWithClassExpression2.errors.txt b/tests/baselines/reference/typeArgumentInferenceWithClassExpression2.errors.txt new file mode 100644 index 00000000000..c630944306b --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceWithClassExpression2.errors.txt @@ -0,0 +1,16 @@ +tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression2.ts(6,5): error TS2345: Argument of type 'typeof (Anonymous class)' is not assignable to parameter of type 'typeof (Anonymous class)'. + Type '(Anonymous class)' is not assignable to type 'foo<{}>.'. + Property 'prop' is missing in type '(Anonymous class)'. + + +==== tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression2.ts (1 errors) ==== + function foo(x = class { prop: T }): T { + return undefined; + } + + // Should not infer string because it is a static property + foo(class { static prop = "hello" }).length; + ~~~~~ +!!! error TS2345: Argument of type 'typeof (Anonymous class)' is not assignable to parameter of type 'typeof (Anonymous class)'. +!!! error TS2345: Type '(Anonymous class)' is not assignable to type 'foo<{}>.'. +!!! error TS2345: Property 'prop' is missing in type '(Anonymous class)'. \ No newline at end of file diff --git a/tests/baselines/reference/typeArgumentInferenceWithClassExpression2.js b/tests/baselines/reference/typeArgumentInferenceWithClassExpression2.js new file mode 100644 index 00000000000..c4a7872b016 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceWithClassExpression2.js @@ -0,0 +1,24 @@ +//// [typeArgumentInferenceWithClassExpression2.ts] +function foo(x = class { prop: T }): T { + return undefined; +} + +// Should not infer string because it is a static property +foo(class { static prop = "hello" }).length; + +//// [typeArgumentInferenceWithClassExpression2.js] +function foo(x) { + if (x === void 0) { x = (function () { + function class_1() { + } + return class_1; + })(); } + return undefined; +} +// Should not infer string because it is a static property +foo((function () { + function class_2() { + } + class_2.prop = "hello"; + return class_2; +})()).length; diff --git a/tests/baselines/reference/typeArgumentInferenceWithClassExpression3.js b/tests/baselines/reference/typeArgumentInferenceWithClassExpression3.js new file mode 100644 index 00000000000..f3a3470e1c3 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceWithClassExpression3.js @@ -0,0 +1,22 @@ +//// [typeArgumentInferenceWithClassExpression3.ts] +function foo(x = class { prop: T }): T { + return undefined; +} + +foo(class { prop = "hello" }).length; + +//// [typeArgumentInferenceWithClassExpression3.js] +function foo(x) { + if (x === void 0) { x = (function () { + function class_1() { + } + return class_1; + })(); } + return undefined; +} +foo((function () { + function class_2() { + this.prop = "hello"; + } + return class_2; +})()).length; diff --git a/tests/baselines/reference/typeArgumentInferenceWithClassExpression3.symbols b/tests/baselines/reference/typeArgumentInferenceWithClassExpression3.symbols new file mode 100644 index 00000000000..aedb0230fd6 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceWithClassExpression3.symbols @@ -0,0 +1,19 @@ +=== tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression3.ts === +function foo(x = class { prop: T }): T { +>foo : Symbol(foo, Decl(typeArgumentInferenceWithClassExpression3.ts, 0, 0)) +>T : Symbol(T, Decl(typeArgumentInferenceWithClassExpression3.ts, 0, 13)) +>x : Symbol(x, Decl(typeArgumentInferenceWithClassExpression3.ts, 0, 16)) +>prop : Symbol((Anonymous class).prop, Decl(typeArgumentInferenceWithClassExpression3.ts, 0, 27)) +>T : Symbol(T, Decl(typeArgumentInferenceWithClassExpression3.ts, 0, 13)) +>T : Symbol(T, Decl(typeArgumentInferenceWithClassExpression3.ts, 0, 13)) + + return undefined; +>undefined : Symbol(undefined) +} + +foo(class { prop = "hello" }).length; +>foo(class { prop = "hello" }).length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) +>foo : Symbol(foo, Decl(typeArgumentInferenceWithClassExpression3.ts, 0, 0)) +>prop : Symbol((Anonymous class).prop, Decl(typeArgumentInferenceWithClassExpression3.ts, 4, 11)) +>length : Symbol(String.length, Decl(lib.d.ts, 414, 19)) + diff --git a/tests/baselines/reference/typeArgumentInferenceWithClassExpression3.types b/tests/baselines/reference/typeArgumentInferenceWithClassExpression3.types new file mode 100644 index 00000000000..9a2bddd9296 --- /dev/null +++ b/tests/baselines/reference/typeArgumentInferenceWithClassExpression3.types @@ -0,0 +1,23 @@ +=== tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression3.ts === +function foo(x = class { prop: T }): T { +>foo : (x?: typeof (Anonymous class)) => T +>T : T +>x : typeof (Anonymous class) +>class { prop: T } : typeof (Anonymous class) +>prop : T +>T : T +>T : T + + return undefined; +>undefined : undefined +} + +foo(class { prop = "hello" }).length; +>foo(class { prop = "hello" }).length : number +>foo(class { prop = "hello" }) : string +>foo : (x?: typeof (Anonymous class)) => T +>class { prop = "hello" } : typeof (Anonymous class) +>prop : string +>"hello" : string +>length : number + diff --git a/tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression.ts b/tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression1.ts similarity index 100% rename from tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression.ts rename to tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression1.ts diff --git a/tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression2.ts b/tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression2.ts new file mode 100644 index 00000000000..d7a901ae951 --- /dev/null +++ b/tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression2.ts @@ -0,0 +1,6 @@ +function foo(x = class { prop: T }): T { + return undefined; +} + +// Should not infer string because it is a static property +foo(class { static prop = "hello" }).length; \ No newline at end of file diff --git a/tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression3.ts b/tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression3.ts new file mode 100644 index 00000000000..d29b7007664 --- /dev/null +++ b/tests/cases/conformance/es6/classExpressions/typeArgumentInferenceWithClassExpression3.ts @@ -0,0 +1,5 @@ +function foo(x = class { prop: T }): T { + return undefined; +} + +foo(class { prop = "hello" }).length; \ No newline at end of file