mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-15 03:23:08 -06:00
support instantiate signature, it has type parameters.
This commit is contained in:
parent
35d6e98e98
commit
ab10d509f5
@ -5365,25 +5365,25 @@ module ts {
|
||||
}
|
||||
}
|
||||
// Target type is type of constructor signiture
|
||||
let constructorSignitures: Signature[];
|
||||
let constructSignitures: Signature[];
|
||||
if (rightType.flags & TypeFlags.Interface) {
|
||||
constructorSignitures = (<InterfaceTypeWithDeclaredMembers>rightType).declaredConstructSignatures;
|
||||
constructSignitures = (<InterfaceTypeWithDeclaredMembers>rightType).declaredConstructSignatures;
|
||||
}
|
||||
if (rightType.flags & TypeFlags.Anonymous) {
|
||||
constructorSignitures = (<ResolvedType>rightType).constructSignatures;
|
||||
constructSignitures = (<ResolvedType>rightType).constructSignatures;
|
||||
}
|
||||
if (constructorSignitures) {
|
||||
let constructorType = getUnionType(map(constructorSignitures, constructorSignature => {
|
||||
if (constructorSignature.typeParameters && constructorSignature.typeParameters.length !== 0) {
|
||||
// TODO convert type parameters to any or empty object types. e.g. Sample<T> -> Sample<any> or Sample<{}>.
|
||||
if (constructSignitures) {
|
||||
let instanceType = getUnionType(map(constructSignitures, constructSignature => {
|
||||
if (constructSignature.typeParameters && constructSignature.typeParameters.length !== 0) {
|
||||
constructSignature = instantiateSignature(constructSignature, createTypeMapper(constructSignature.typeParameters, map(constructSignature.typeParameters, _ => anyType)), true)
|
||||
}
|
||||
return constructorSignature.resolvedReturnType;
|
||||
return constructSignature.resolvedReturnType;
|
||||
}));
|
||||
// Pickup type from union types
|
||||
if (type.flags & TypeFlags.Union) {
|
||||
return getUnionType(filter((<UnionType>type).types, t => isTypeSubtypeOf(t, constructorType)));
|
||||
return getUnionType(filter((<UnionType>type).types, t => isTypeSubtypeOf(t, instanceType)));
|
||||
}
|
||||
return constructorType;
|
||||
return instanceType;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
@ -1,12 +1,16 @@
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(12,10): error TS2339: Property 'bar' does not exist on type 'A'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(32,10): error TS2339: Property 'foo' does not exist on type '{}'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(33,10): error TS2339: Property 'foo' does not exist on type '{}'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(34,10): error TS2339: Property 'bar' does not exist on type '{}'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(33,5): error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(34,10): error TS2339: Property 'bar' does not exist on type 'B<number>'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(63,10): error TS2339: Property 'bar2' does not exist on type 'C1'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(82,10): error TS2339: Property 'bar' does not exist on type 'D'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(109,10): error TS2339: Property 'bar2' does not exist on type 'E1'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(131,11): error TS2339: Property 'foo' does not exist on type 'string | F'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(132,11): error TS2339: Property 'bar' does not exist on type 'string | F'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(157,11): error TS2339: Property 'foo2' does not exist on type 'G1'.
|
||||
tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts(179,11): error TS2339: Property 'bar' does not exist on type 'H'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts (6 errors) ====
|
||||
==== tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstructorSignature.ts (10 errors) ====
|
||||
interface AConstructor {
|
||||
new (): A;
|
||||
}
|
||||
@ -29,7 +33,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstru
|
||||
obj2.bar;
|
||||
}
|
||||
|
||||
// with generics
|
||||
// a construct signature with generics
|
||||
interface BConstructor {
|
||||
new <T>(): B<T>;
|
||||
}
|
||||
@ -38,17 +42,15 @@ tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstru
|
||||
}
|
||||
declare var B: BConstructor;
|
||||
|
||||
var obj3: B<string> | A;
|
||||
if (obj3 instanceof B) { // narrowed to B<string>.
|
||||
obj3.foo = "str";
|
||||
~~~
|
||||
!!! error TS2339: Property 'foo' does not exist on type '{}'.
|
||||
var obj3: B<number> | string;
|
||||
if (obj3 instanceof B) { // narrowed to B<number>.
|
||||
obj3.foo = 1;
|
||||
~~~
|
||||
!!! error TS2339: Property 'foo' does not exist on type '{}'.
|
||||
obj3.foo = "str";
|
||||
~~~~~~~~
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'number'.
|
||||
obj3.bar = "str";
|
||||
~~~
|
||||
!!! error TS2339: Property 'bar' does not exist on type '{}'.
|
||||
!!! error TS2339: Property 'bar' does not exist on type 'B<number>'.
|
||||
}
|
||||
|
||||
var obj4: any;
|
||||
@ -58,7 +60,7 @@ tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstru
|
||||
obj4.bar = "str";
|
||||
}
|
||||
|
||||
// has multiple constructor signature
|
||||
// has multiple construct signature
|
||||
interface CConstructor {
|
||||
new (value: string): C1;
|
||||
new (value: number): C2;
|
||||
@ -108,4 +110,111 @@ tests/cases/conformance/expressions/typeGuards/typeGuardsWithInstanceOfByConstru
|
||||
obj8.foo;
|
||||
obj8.bar;
|
||||
}
|
||||
|
||||
// a construct signature that returns a union type
|
||||
interface EConstructor {
|
||||
new (): E1 | E2;
|
||||
}
|
||||
interface E1 {
|
||||
foo: string;
|
||||
bar1: number;
|
||||
}
|
||||
interface E2 {
|
||||
foo: string;
|
||||
bar2: number;
|
||||
}
|
||||
declare var E: EConstructor;
|
||||
|
||||
var obj9: E1 | A;
|
||||
if (obj9 instanceof E) { // narrowed to E1.
|
||||
obj9.foo;
|
||||
obj9.bar1;
|
||||
obj9.bar2;
|
||||
~~~~
|
||||
!!! error TS2339: Property 'bar2' does not exist on type 'E1'.
|
||||
}
|
||||
|
||||
var obj10: any;
|
||||
if (obj10 instanceof E) { // can't type narrowing from any.
|
||||
obj10.foo;
|
||||
obj10.bar1;
|
||||
obj10.bar2;
|
||||
}
|
||||
|
||||
// a construct signature that returns any
|
||||
interface FConstructor {
|
||||
new (): any;
|
||||
}
|
||||
interface F {
|
||||
foo: string;
|
||||
bar: number;
|
||||
}
|
||||
declare var F: FConstructor;
|
||||
|
||||
var obj11: F | string;
|
||||
if (obj11 instanceof F) { // can't type narrowing, construct signiture returns any.
|
||||
obj11.foo;
|
||||
~~~
|
||||
!!! error TS2339: Property 'foo' does not exist on type 'string | F'.
|
||||
obj11.bar;
|
||||
~~~
|
||||
!!! error TS2339: Property 'bar' does not exist on type 'string | F'.
|
||||
}
|
||||
|
||||
var obj12: any;
|
||||
if (obj12 instanceof F) { // can't type narrowing from any.
|
||||
obj12.foo;
|
||||
obj12.bar;
|
||||
}
|
||||
|
||||
// a type with a prototype, it overrides the construct signiture
|
||||
interface GConstructor {
|
||||
prototype: G1; // high priority
|
||||
new (): G2; // low priority
|
||||
}
|
||||
interface G1 {
|
||||
foo1: number;
|
||||
}
|
||||
interface G2 {
|
||||
foo2: boolean;
|
||||
}
|
||||
declare var G: GConstructor;
|
||||
|
||||
var obj13: G1 | G2;
|
||||
if (obj13 instanceof G) { // narrowed to G1. G1 is return type of prototype property.
|
||||
obj13.foo1;
|
||||
obj13.foo2;
|
||||
~~~~
|
||||
!!! error TS2339: Property 'foo2' does not exist on type 'G1'.
|
||||
}
|
||||
|
||||
var obj14: any;
|
||||
if (obj14 instanceof G) { // can't type narrowing from any.
|
||||
obj14.foo1;
|
||||
obj14.foo2;
|
||||
}
|
||||
|
||||
// a type with a prototype that has any type
|
||||
interface HConstructor {
|
||||
prototype: any; // high priority, but any type is ignored. interface has implicit `prototype: any`.
|
||||
new (): H; // low priority
|
||||
}
|
||||
interface H {
|
||||
foo: number;
|
||||
}
|
||||
declare var H: HConstructor;
|
||||
|
||||
var obj15: H | string;
|
||||
if (obj15 instanceof H) { // narrowed to H.
|
||||
obj15.foo;
|
||||
obj15.bar;
|
||||
~~~
|
||||
!!! error TS2339: Property 'bar' does not exist on type 'H'.
|
||||
}
|
||||
|
||||
var obj16: any;
|
||||
if (obj16 instanceof H) { // can't type narrowing from any.
|
||||
obj16.foo1;
|
||||
obj16.foo2;
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ if (obj2 instanceof A) { // can't type narrowing from any.
|
||||
obj2.bar;
|
||||
}
|
||||
|
||||
// with generics
|
||||
// a construct signature with generics
|
||||
interface BConstructor {
|
||||
new <T>(): B<T>;
|
||||
}
|
||||
@ -28,10 +28,10 @@ interface B<T> {
|
||||
}
|
||||
declare var B: BConstructor;
|
||||
|
||||
var obj3: B<string> | A;
|
||||
if (obj3 instanceof B) { // narrowed to B<string>.
|
||||
obj3.foo = "str";
|
||||
var obj3: B<number> | string;
|
||||
if (obj3 instanceof B) { // narrowed to B<number>.
|
||||
obj3.foo = 1;
|
||||
obj3.foo = "str";
|
||||
obj3.bar = "str";
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ if (obj4 instanceof B) { // can't type narrowing from any.
|
||||
obj4.bar = "str";
|
||||
}
|
||||
|
||||
// has multiple constructor signature
|
||||
// has multiple construct signature
|
||||
interface CConstructor {
|
||||
new (value: string): C1;
|
||||
new (value: number): C2;
|
||||
@ -89,6 +89,103 @@ if (obj8 instanceof D) { // can't type narrowing from any.
|
||||
obj8.bar;
|
||||
}
|
||||
|
||||
// a construct signature that returns a union type
|
||||
interface EConstructor {
|
||||
new (): E1 | E2;
|
||||
}
|
||||
interface E1 {
|
||||
foo: string;
|
||||
bar1: number;
|
||||
}
|
||||
interface E2 {
|
||||
foo: string;
|
||||
bar2: number;
|
||||
}
|
||||
declare var E: EConstructor;
|
||||
|
||||
var obj9: E1 | A;
|
||||
if (obj9 instanceof E) { // narrowed to E1.
|
||||
obj9.foo;
|
||||
obj9.bar1;
|
||||
obj9.bar2;
|
||||
}
|
||||
|
||||
var obj10: any;
|
||||
if (obj10 instanceof E) { // can't type narrowing from any.
|
||||
obj10.foo;
|
||||
obj10.bar1;
|
||||
obj10.bar2;
|
||||
}
|
||||
|
||||
// a construct signature that returns any
|
||||
interface FConstructor {
|
||||
new (): any;
|
||||
}
|
||||
interface F {
|
||||
foo: string;
|
||||
bar: number;
|
||||
}
|
||||
declare var F: FConstructor;
|
||||
|
||||
var obj11: F | string;
|
||||
if (obj11 instanceof F) { // can't type narrowing, construct signiture returns any.
|
||||
obj11.foo;
|
||||
obj11.bar;
|
||||
}
|
||||
|
||||
var obj12: any;
|
||||
if (obj12 instanceof F) { // can't type narrowing from any.
|
||||
obj12.foo;
|
||||
obj12.bar;
|
||||
}
|
||||
|
||||
// a type with a prototype, it overrides the construct signiture
|
||||
interface GConstructor {
|
||||
prototype: G1; // high priority
|
||||
new (): G2; // low priority
|
||||
}
|
||||
interface G1 {
|
||||
foo1: number;
|
||||
}
|
||||
interface G2 {
|
||||
foo2: boolean;
|
||||
}
|
||||
declare var G: GConstructor;
|
||||
|
||||
var obj13: G1 | G2;
|
||||
if (obj13 instanceof G) { // narrowed to G1. G1 is return type of prototype property.
|
||||
obj13.foo1;
|
||||
obj13.foo2;
|
||||
}
|
||||
|
||||
var obj14: any;
|
||||
if (obj14 instanceof G) { // can't type narrowing from any.
|
||||
obj14.foo1;
|
||||
obj14.foo2;
|
||||
}
|
||||
|
||||
// a type with a prototype that has any type
|
||||
interface HConstructor {
|
||||
prototype: any; // high priority, but any type is ignored. interface has implicit `prototype: any`.
|
||||
new (): H; // low priority
|
||||
}
|
||||
interface H {
|
||||
foo: number;
|
||||
}
|
||||
declare var H: HConstructor;
|
||||
|
||||
var obj15: H | string;
|
||||
if (obj15 instanceof H) { // narrowed to H.
|
||||
obj15.foo;
|
||||
obj15.bar;
|
||||
}
|
||||
|
||||
var obj16: any;
|
||||
if (obj16 instanceof H) { // can't type narrowing from any.
|
||||
obj16.foo1;
|
||||
obj16.foo2;
|
||||
}
|
||||
|
||||
|
||||
//// [typeGuardsWithInstanceOfByConstructorSignature.js]
|
||||
var obj1;
|
||||
@ -103,8 +200,8 @@ if (obj2 instanceof A) {
|
||||
}
|
||||
var obj3;
|
||||
if (obj3 instanceof B) {
|
||||
obj3.foo = "str";
|
||||
obj3.foo = 1;
|
||||
obj3.foo = "str";
|
||||
obj3.bar = "str";
|
||||
}
|
||||
var obj4;
|
||||
@ -135,3 +232,45 @@ if (obj8 instanceof D) {
|
||||
obj8.foo;
|
||||
obj8.bar;
|
||||
}
|
||||
var obj9;
|
||||
if (obj9 instanceof E) {
|
||||
obj9.foo;
|
||||
obj9.bar1;
|
||||
obj9.bar2;
|
||||
}
|
||||
var obj10;
|
||||
if (obj10 instanceof E) {
|
||||
obj10.foo;
|
||||
obj10.bar1;
|
||||
obj10.bar2;
|
||||
}
|
||||
var obj11;
|
||||
if (obj11 instanceof F) {
|
||||
obj11.foo;
|
||||
obj11.bar;
|
||||
}
|
||||
var obj12;
|
||||
if (obj12 instanceof F) {
|
||||
obj12.foo;
|
||||
obj12.bar;
|
||||
}
|
||||
var obj13;
|
||||
if (obj13 instanceof G) {
|
||||
obj13.foo1;
|
||||
obj13.foo2;
|
||||
}
|
||||
var obj14;
|
||||
if (obj14 instanceof G) {
|
||||
obj14.foo1;
|
||||
obj14.foo2;
|
||||
}
|
||||
var obj15;
|
||||
if (obj15 instanceof H) {
|
||||
obj15.foo;
|
||||
obj15.bar;
|
||||
}
|
||||
var obj16;
|
||||
if (obj16 instanceof H) {
|
||||
obj16.foo1;
|
||||
obj16.foo2;
|
||||
}
|
||||
|
||||
@ -18,7 +18,7 @@ if (obj2 instanceof A) { // can't type narrowing from any.
|
||||
obj2.bar;
|
||||
}
|
||||
|
||||
// with generics
|
||||
// a construct signature with generics
|
||||
interface BConstructor {
|
||||
new <T>(): B<T>;
|
||||
}
|
||||
@ -27,10 +27,10 @@ interface B<T> {
|
||||
}
|
||||
declare var B: BConstructor;
|
||||
|
||||
var obj3: B<string> | A;
|
||||
if (obj3 instanceof B) { // narrowed to B<string>.
|
||||
obj3.foo = "str";
|
||||
var obj3: B<number> | string;
|
||||
if (obj3 instanceof B) { // narrowed to B<number>.
|
||||
obj3.foo = 1;
|
||||
obj3.foo = "str";
|
||||
obj3.bar = "str";
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ if (obj4 instanceof B) { // can't type narrowing from any.
|
||||
obj4.bar = "str";
|
||||
}
|
||||
|
||||
// has multiple constructor signature
|
||||
// has multiple construct signature
|
||||
interface CConstructor {
|
||||
new (value: string): C1;
|
||||
new (value: number): C2;
|
||||
@ -87,3 +87,100 @@ if (obj8 instanceof D) { // can't type narrowing from any.
|
||||
obj8.foo;
|
||||
obj8.bar;
|
||||
}
|
||||
|
||||
// a construct signature that returns a union type
|
||||
interface EConstructor {
|
||||
new (): E1 | E2;
|
||||
}
|
||||
interface E1 {
|
||||
foo: string;
|
||||
bar1: number;
|
||||
}
|
||||
interface E2 {
|
||||
foo: string;
|
||||
bar2: number;
|
||||
}
|
||||
declare var E: EConstructor;
|
||||
|
||||
var obj9: E1 | A;
|
||||
if (obj9 instanceof E) { // narrowed to E1.
|
||||
obj9.foo;
|
||||
obj9.bar1;
|
||||
obj9.bar2;
|
||||
}
|
||||
|
||||
var obj10: any;
|
||||
if (obj10 instanceof E) { // can't type narrowing from any.
|
||||
obj10.foo;
|
||||
obj10.bar1;
|
||||
obj10.bar2;
|
||||
}
|
||||
|
||||
// a construct signature that returns any
|
||||
interface FConstructor {
|
||||
new (): any;
|
||||
}
|
||||
interface F {
|
||||
foo: string;
|
||||
bar: number;
|
||||
}
|
||||
declare var F: FConstructor;
|
||||
|
||||
var obj11: F | string;
|
||||
if (obj11 instanceof F) { // can't type narrowing, construct signiture returns any.
|
||||
obj11.foo;
|
||||
obj11.bar;
|
||||
}
|
||||
|
||||
var obj12: any;
|
||||
if (obj12 instanceof F) { // can't type narrowing from any.
|
||||
obj12.foo;
|
||||
obj12.bar;
|
||||
}
|
||||
|
||||
// a type with a prototype, it overrides the construct signiture
|
||||
interface GConstructor {
|
||||
prototype: G1; // high priority
|
||||
new (): G2; // low priority
|
||||
}
|
||||
interface G1 {
|
||||
foo1: number;
|
||||
}
|
||||
interface G2 {
|
||||
foo2: boolean;
|
||||
}
|
||||
declare var G: GConstructor;
|
||||
|
||||
var obj13: G1 | G2;
|
||||
if (obj13 instanceof G) { // narrowed to G1. G1 is return type of prototype property.
|
||||
obj13.foo1;
|
||||
obj13.foo2;
|
||||
}
|
||||
|
||||
var obj14: any;
|
||||
if (obj14 instanceof G) { // can't type narrowing from any.
|
||||
obj14.foo1;
|
||||
obj14.foo2;
|
||||
}
|
||||
|
||||
// a type with a prototype that has any type
|
||||
interface HConstructor {
|
||||
prototype: any; // high priority, but any type is ignored. interface has implicit `prototype: any`.
|
||||
new (): H; // low priority
|
||||
}
|
||||
interface H {
|
||||
foo: number;
|
||||
}
|
||||
declare var H: HConstructor;
|
||||
|
||||
var obj15: H | string;
|
||||
if (obj15 instanceof H) { // narrowed to H.
|
||||
obj15.foo;
|
||||
obj15.bar;
|
||||
}
|
||||
|
||||
var obj16: any;
|
||||
if (obj16 instanceof H) { // can't type narrowing from any.
|
||||
obj16.foo1;
|
||||
obj16.foo2;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user