diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a8f8b3a5e16..20e813939cc 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13077,8 +13077,11 @@ namespace ts { // object type literal or interface (using the new keyword). Each way of declaring a constructor // will result in a different declaration kind. if (!signature.isolatedSignatureType) { - const kind = signature.declaration ? signature.declaration.kind : SyntaxKind.Unknown; - const isConstructor = kind === SyntaxKind.Constructor || kind === SyntaxKind.ConstructSignature || kind === SyntaxKind.ConstructorType; + const kind = signature.declaration?.kind; + + // If declaration is undefined, it is likely to be the signature of the default constructor. + const isConstructor = kind === undefined || kind === SyntaxKind.Constructor || kind === SyntaxKind.ConstructSignature || kind === SyntaxKind.ConstructorType; + const type = createObjectType(ObjectFlags.Anonymous); type.members = emptySymbols; type.properties = emptyArray; diff --git a/tests/baselines/reference/inferringReturnTypeFromConstructSignatureGeneric.js b/tests/baselines/reference/inferringReturnTypeFromConstructSignatureGeneric.js new file mode 100644 index 00000000000..a2f19cc2a3f --- /dev/null +++ b/tests/baselines/reference/inferringReturnTypeFromConstructSignatureGeneric.js @@ -0,0 +1,66 @@ +//// [inferringReturnTypeFromConstructSignatureGeneric.ts] +class GenericObject { + give(value: T) { + return value; + } +} +class GenericNumber { + give(value: T) { + return value; + } +} +class GenericNumberOrString { + give(value: T) { + return value; + } +} + +function g(type: new () => T): T { + return new type(); +} + +const g1 = g(GenericObject); +g1.give({}); + +const g2 = g(GenericNumber); +g2.give(1); + +const g3 = g(GenericNumberOrString); +g3.give(1); +g3.give('1'); + +//// [inferringReturnTypeFromConstructSignatureGeneric.js] +var GenericObject = /** @class */ (function () { + function GenericObject() { + } + GenericObject.prototype.give = function (value) { + return value; + }; + return GenericObject; +}()); +var GenericNumber = /** @class */ (function () { + function GenericNumber() { + } + GenericNumber.prototype.give = function (value) { + return value; + }; + return GenericNumber; +}()); +var GenericNumberOrString = /** @class */ (function () { + function GenericNumberOrString() { + } + GenericNumberOrString.prototype.give = function (value) { + return value; + }; + return GenericNumberOrString; +}()); +function g(type) { + return new type(); +} +var g1 = g(GenericObject); +g1.give({}); +var g2 = g(GenericNumber); +g2.give(1); +var g3 = g(GenericNumberOrString); +g3.give(1); +g3.give('1'); diff --git a/tests/baselines/reference/inferringReturnTypeFromConstructSignatureGeneric.symbols b/tests/baselines/reference/inferringReturnTypeFromConstructSignatureGeneric.symbols new file mode 100644 index 00000000000..3d711376681 --- /dev/null +++ b/tests/baselines/reference/inferringReturnTypeFromConstructSignatureGeneric.symbols @@ -0,0 +1,87 @@ +=== tests/cases/compiler/inferringReturnTypeFromConstructSignatureGeneric.ts === +class GenericObject { +>GenericObject : Symbol(GenericObject, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 0, 0)) +>T : Symbol(T, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 0, 20)) + + give(value: T) { +>give : Symbol(GenericObject.give, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 0, 40)) +>value : Symbol(value, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 1, 7)) +>T : Symbol(T, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 0, 20)) + + return value; +>value : Symbol(value, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 1, 7)) + } +} +class GenericNumber { +>GenericNumber : Symbol(GenericNumber, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 4, 1)) +>T : Symbol(T, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 5, 20)) + + give(value: T) { +>give : Symbol(GenericNumber.give, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 5, 39)) +>value : Symbol(value, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 6, 7)) +>T : Symbol(T, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 5, 20)) + + return value; +>value : Symbol(value, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 6, 7)) + } +} +class GenericNumberOrString { +>GenericNumberOrString : Symbol(GenericNumberOrString, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 9, 1)) +>T : Symbol(T, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 10, 28)) + + give(value: T) { +>give : Symbol(GenericNumberOrString.give, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 10, 56)) +>value : Symbol(value, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 11, 7)) +>T : Symbol(T, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 10, 28)) + + return value; +>value : Symbol(value, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 11, 7)) + } +} + +function g(type: new () => T): T { +>g : Symbol(g, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 14, 1)) +>T : Symbol(T, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 16, 11)) +>type : Symbol(type, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 16, 14)) +>T : Symbol(T, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 16, 11)) +>T : Symbol(T, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 16, 11)) + + return new type(); +>type : Symbol(type, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 16, 14)) +} + +const g1 = g(GenericObject); +>g1 : Symbol(g1, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 20, 5)) +>g : Symbol(g, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 14, 1)) +>GenericObject : Symbol(GenericObject, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 0, 0)) + +g1.give({}); +>g1.give : Symbol(GenericObject.give, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 0, 40)) +>g1 : Symbol(g1, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 20, 5)) +>give : Symbol(GenericObject.give, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 0, 40)) + +const g2 = g(GenericNumber); +>g2 : Symbol(g2, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 23, 5)) +>g : Symbol(g, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 14, 1)) +>GenericNumber : Symbol(GenericNumber, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 4, 1)) + +g2.give(1); +>g2.give : Symbol(GenericNumber.give, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 5, 39)) +>g2 : Symbol(g2, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 23, 5)) +>give : Symbol(GenericNumber.give, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 5, 39)) + +const g3 = g(GenericNumberOrString); +>g3 : Symbol(g3, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 26, 5)) +>g : Symbol(g, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 14, 1)) +>GenericNumberOrString : Symbol(GenericNumberOrString, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 9, 1)) + +g3.give(1); +>g3.give : Symbol(GenericNumberOrString.give, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 10, 56)) +>g3 : Symbol(g3, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 26, 5)) +>give : Symbol(GenericNumberOrString.give, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 10, 56)) + +g3.give('1'); +>g3.give : Symbol(GenericNumberOrString.give, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 10, 56)) +>g3 : Symbol(g3, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 26, 5)) +>give : Symbol(GenericNumberOrString.give, Decl(inferringReturnTypeFromConstructSignatureGeneric.ts, 10, 56)) + diff --git a/tests/baselines/reference/inferringReturnTypeFromConstructSignatureGeneric.types b/tests/baselines/reference/inferringReturnTypeFromConstructSignatureGeneric.types new file mode 100644 index 00000000000..5d641a66e09 --- /dev/null +++ b/tests/baselines/reference/inferringReturnTypeFromConstructSignatureGeneric.types @@ -0,0 +1,90 @@ +=== tests/cases/compiler/inferringReturnTypeFromConstructSignatureGeneric.ts === +class GenericObject { +>GenericObject : GenericObject + + give(value: T) { +>give : (value: T) => T +>value : T + + return value; +>value : T + } +} +class GenericNumber { +>GenericNumber : GenericNumber + + give(value: T) { +>give : (value: T) => T +>value : T + + return value; +>value : T + } +} +class GenericNumberOrString { +>GenericNumberOrString : GenericNumberOrString + + give(value: T) { +>give : (value: T) => T +>value : T + + return value; +>value : T + } +} + +function g(type: new () => T): T { +>g : (type: new () => T) => T +>type : new () => T + + return new type(); +>new type() : T +>type : new () => T +} + +const g1 = g(GenericObject); +>g1 : GenericObject<{}> +>g(GenericObject) : GenericObject<{}> +>g : (type: new () => T) => T +>GenericObject : typeof GenericObject + +g1.give({}); +>g1.give({}) : {} +>g1.give : (value: {}) => {} +>g1 : GenericObject<{}> +>give : (value: {}) => {} +>{} : {} + +const g2 = g(GenericNumber); +>g2 : GenericNumber +>g(GenericNumber) : GenericNumber +>g : (type: new () => T) => T +>GenericNumber : typeof GenericNumber + +g2.give(1); +>g2.give(1) : number +>g2.give : (value: number) => number +>g2 : GenericNumber +>give : (value: number) => number +>1 : 1 + +const g3 = g(GenericNumberOrString); +>g3 : GenericNumberOrString +>g(GenericNumberOrString) : GenericNumberOrString +>g : (type: new () => T) => T +>GenericNumberOrString : typeof GenericNumberOrString + +g3.give(1); +>g3.give(1) : string | number +>g3.give : (value: string | number) => string | number +>g3 : GenericNumberOrString +>give : (value: string | number) => string | number +>1 : 1 + +g3.give('1'); +>g3.give('1') : string | number +>g3.give : (value: string | number) => string | number +>g3 : GenericNumberOrString +>give : (value: string | number) => string | number +>'1' : "1" + diff --git a/tests/cases/compiler/inferringReturnTypeFromConstructSignatureGeneric.ts b/tests/cases/compiler/inferringReturnTypeFromConstructSignatureGeneric.ts new file mode 100644 index 00000000000..dc8271f849b --- /dev/null +++ b/tests/cases/compiler/inferringReturnTypeFromConstructSignatureGeneric.ts @@ -0,0 +1,29 @@ +class GenericObject { + give(value: T) { + return value; + } +} +class GenericNumber { + give(value: T) { + return value; + } +} +class GenericNumberOrString { + give(value: T) { + return value; + } +} + +function g(type: new () => T): T { + return new type(); +} + +const g1 = g(GenericObject); +g1.give({}); + +const g2 = g(GenericNumber); +g2.give(1); + +const g3 = g(GenericNumberOrString); +g3.give(1); +g3.give('1'); \ No newline at end of file