Repository navigation
Closed
Labels
BugA bug in TypeScriptA bug in TypeScriptDomain: Declaration EmitThe issue relates to the emission of d.ts filesThe issue relates to the emission of d.ts filesFixedA PR has been merged for this issueA PR has been merged for this issueHigh Priority
Milestone
Description
TypeScript Version: 2.5.2
Code
I created some code to ensure that developer will create only one class with specific 'kind' property used in discriminated union:
const kindCache: { [kind: string]: boolean } = {};
function register(kind: string): void | never {
if (kindCache[kind]) {
throw new Error(`Class with kind "${kind}" is already registered.`);
}
kindCache[kind] = true;
}
function ClassFactory<TKind extends string>(kind: TKind) {
register(kind);
return class {
static readonly THE_KIND: TKind = kind;
readonly kind: TKind = kind;
};
}
class Kinds {
static readonly A = "A";
static readonly B = "B";
static readonly C = "C";
}
export class AKind extends ClassFactory(Kinds.A) {
}
export class BKind extends ClassFactory(Kinds.B) {
}
export class CKind extends ClassFactory(Kinds.C) {
}Locally it works as expected. Compilation of:
const x: AKind = new BKind();causes error:
error TS2322: Type 'BKind' is not assignable to type 'AKind'.
Types of property 'kind' are incompatible.
Type '"B"' is not assignable to type '"A"'.Expected behavior:
I expected that it will generate d.ts like this:
declare const AKind_base: {
new (): {
readonly kind: "A";
};
readonly THE_KIND: "A";
};
export declare class AKind extends AKind_base {
}
declare const BKind_base: {
new (): {
readonly kind: "B";
};
readonly THE_KIND: "B";
};
export declare class BKind extends BKind_base {
}
declare const CKind_base: {
new (): {
readonly kind: "C";
};
readonly THE_KIND: "C";
};
export declare class CKind extends CKind_base {
}Actual behavior:
But type of non-static field is invalid (TKind)
declare const AKind_base: {
new (): {
readonly kind: TKind;
};
readonly THE_KIND: "A";
};
export declare class AKind extends AKind_base {
}
declare const BKind_base: {
new (): {
readonly kind: TKind;
};
readonly THE_KIND: "B";
};
export declare class BKind extends BKind_base {
}
declare const CKind_base: {
new (): {
readonly kind: TKind;
};
readonly THE_KIND: "C";
};
export declare class CKind extends CKind_base {
}Reacted by Tadeusz and Manuel Alabor
Metadata
Metadata
Assignees
Labels
BugA bug in TypeScriptA bug in TypeScriptDomain: Declaration EmitThe issue relates to the emission of d.ts filesThe issue relates to the emission of d.ts filesFixedA PR has been merged for this issueA PR has been merged for this issueHigh Priority
Activity
damian-lewkowicz commentedon Sep 18, 2017
Aluan Haddad (@aluanhaddad) it will produce the wrong d.ts as well
appsforartists commentedon Sep 28, 2017
Here's a simpler reproduction:
and the resulting (broken)
d.ts:Fix microsoft#18545, dont use declared type of class expression
Fix microsoft#18545, dont use declared type of class expression
Fix instantiated generic mixin declaration emit (#19144)
Port master into release-2.6 10/16 (#19237)