microsoft / microsoft/TypeScript

Mixin / Inheritance problem with Typescript - string not assignable to string|number|symbol

Ouverte
#52,907 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Bug Domain: classes Help Wanted
Langage dominant
Go
Étoiles
111k
Forks
14.4k
Merge moyen
1 j 19 h
PR mergées (30 j)
117

Description

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.

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par la reproduction liée dans TypeScript Playground et comparez-la avec le contournement lié, en vous concentrant sur la gestion des mixins génériques et de l’héritage. L’issue est terminée lorsque l’exemple d’origine passe la vérification de types sans le contournement tout en préservant le type 'User' à travers UserRecord.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
typescript
Domaine
compilers
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.