-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compile errors with a generic base class and class mixins using declarative typings #14017
Comments
Your example has several syntax errors and missing imports in it. However, once I fix it up the following compiles with no errors: // BaseClass.ts
export type Constructor<T> = new (...args: any[]) => T;
export class MyBaseClass<T> {
baseProperty: string;
constructor(value: T) {}
} // MixinClass.ts
import { Constructor, MyBaseClass } from './BaseClass';
export interface MyMixin {
mixinProperty: string;
}
export function MyMixin<T extends Constructor<MyBaseClass<any>>>(base: T): T & Constructor<MyMixin> {
return class extends base {
mixinProperty: string;
}
} // FinalClass.ts
import { MyBaseClass } from './BaseClass';
import { MyMixin } from './MixinClass';
export class MyExtendedClass extends MyMixin(MyBaseClass)<string> {
extendedClassProperty: number;
} // Main.ts
import { MyExtendedClass } from './FinalClass';
import { MyMixin } from './MixinClass';
const myExtendedClass = new MyExtendedClass('string');
const AnotherMixedClass = MyMixin(MyExtendedClass); |
@ahejlsberg Thanks for looking. Was it the GitHub repro that was wrong? Or my the example code on the issue? Or both? |
The honest answer is I want you to be correct. But I really struggled to get anything compiling given the 'd.ts' typings generated from core code in the example. |
@ahejlsberg did you try Note: I see the copy/paste fail in the code I put on the issue (sorry about that). |
Ah, I see what the problem is now. The declaration file emitter is emitting incorrect code in FinalClass.d.ts: // FinalClass.d.ts
import { MyBaseClass } from './BaseClass';
import { MyMixin } from './MixinClass';
export declare class MyExtendedClass extends MyBaseClass<string> & MyMixin {
extendedClassProperty: number;
} The You can work around the issue by introducing a // FinalClass.ts
import { Constructor, MyBaseClass } from './BaseClass';
import { MyMixin } from './MixinClass';
export const MyMixedBaseClass = MyMixin(MyBaseClass);
export class MyExtendedClass extends MyMixedBaseClass<string> {
extendedClassProperty: number;
} That produces the following correct output: // FinalClass.d.ts
import { Constructor, MyBaseClass } from './BaseClass';
import { MyMixin } from './MixinClass';
export declare const MyMixedBaseClass: typeof MyBaseClass & Constructor<MyMixin>;
export declare class MyExtendedClass extends MyMixedBaseClass<string> {
extendedClassProperty: number;
} |
Great, thank you - I will try that out now (perhaps I should have just put the emitted code from Is it just a side effect that is works when a generic is not passed? Because without a generic the emitted code is export declare class MyExtendedClass extends MyBaseClass & MyMixin {
extendedClassProperty: number;
} So still a type but behaves as expected? |
@agubler extending an intersection still doesn't work though — it fails in the parser (and has no supporting code in the checker either). After some discussion, we're going to make it a d.ts error for 2.2 and consider supporting |
@sandersn Thanks for the feedback, the work around to assign the result of the mixins to a intermediary |
Yes, it's just a limitation of the parsing and checking of heritage clauses — they expect a type reference, not an arbitrary expression. |
I thought as much, at least with it being an error the issue will be highlighted before we try to consume the published module(s). |
Initial fix is up at #14074 I'll look at actually parsing intersections after this so that it's no longer an error. |
TypeScript Version: 2.2.0 (rc) & 2.2.0-dev.20170211
I am having trouble creating consumable typings when using class mixins for a generic class from a core library - github example repro here https://github.com/agubler/typescript-mixin-typings.
Consider the following provided by a core library
compiling with
declarations
true
Usage in downstream consumer project:
Errors:
5 col 25 error| Supplied parameters do not match any signature of call target. [typescript/tsuquyomi]
8 col 35 error| Argument of type 'typeof MyExtendedClass' is not assignable to parameter of type 'Constructor<MyBaseClass<any>>'. Type 'MyExtendedClass' is not assignable to type 'MyBaseClass<any>'. Property 'baseProperty' is missing in type 'MyExtendedClass'. [typescript/tsuquyomi]
The text was updated successfully, but these errors were encountered: