Mixin / Inheritance problem with Typescript - string not assignable to string|number|symbol
#52,907 opened on 2023年2月22日
Repository metrics
- Stars
- (48,455 stars)
- PR merge metrics
- (平均マージ 6d 17h) (30d で 9 merged PRs)
説明
Bug Report
I have a typescript class. I'd like to subclass it and add a mixin. However, it keeps telling me that string not assignable to string|number|symbol. I don't understand why because the method signatures are the same.
🔎 Search Terms
typescript mixin prototype
🕗 Version & Regression Information
4.9.5
I just started using Typescript, so 4.9.5 is the version I was using since I started seeing it.
⏯ Playground Link
this shows the problem with UserRecord
this shows the way to work around the problem
💻 Code
This is as short as I can make the example and still show what's happening:
type TModel = {
'User' : {
username : string,
password : string | undefined,
},
'APIKey' : {
privateKey: string,
}
};
type TProps<T extends keyof TModel> = Partial<TModel[T]>;
type Constructor<T = {}> = new (...args: any[]) => T;
class VingRecord<T extends keyof TModel> {
constructor( private props: TProps<T>) { }
public set<K extends keyof TProps<T>>(_key: K) {}
}
function RoleMixin<T extends Constructor>(Base: T) {
return class RoleMixin extends Base { };
}
class UserRecord extends RoleMixin(VingRecord<'User'>) {
public set<K extends keyof TProps<'User'>>(_key: K) {}
}
and if you replace the RoleMixin with this it hides the problem with the funky prototype:
function RoleMixin<T extends IConstructable>(Base: T) {
class RoleMixin extends Base {};
return RoleMixin as {
new (...args: any): RoleMixin;
prototype: any;
} & T;
}
🙁 Actual behavior
The code works, but typescript has a problem with the mixin thinking the type on VingRecord is any rather than 'User'. So it reports a type mismatch on the UserRecord.
More detail here with the guys who spotted the behavior
🙂 Expected behavior
I should be able to do the inheritance as shown in the code sample above without having to do the funky return from the mixin.