J'ai un objet tapé comme

interface Asset {
  id: string;
}

interface Project {
  assets: Array<string> | Array<Asset>;
}

Maintenant, si je lance ce qui suit:

const project: Project = {
  assets: [
    {id: '1'}.
    {id: '2'},
    {id: '3'},
    {id: '4'}
  ],
};
project.assets.map((asset: Asset) => asset.id);

Je reçois cette erreur

Impossible d'appeler une expression dont le type n'a pas de signature d'appel. Tapez '((callbackfn: (value: string, index: number, array: string []) => U, thisArg ?: any) => U []) | ((callbackfn: (value: Asset, index: number, array: Asset []) => U, thisArg ?: any) => U []) 'n'a pas de signatures d'appel compatibles.

Cette erreur persiste même si je change le rappel en

project.assets.map((asset: Asset | string) => {console.log(asset)});

Pourquoi cela se produit-il et comment résoudre ce problème?

0
ManavM 19 juin 2019 à 10:08

3 réponses

Meilleure réponse

C'est parce que TS ne peut pas déterminer quel est le type final de votre tableau project.assets. Vous pouvez appeler la fonction map comme ceci avec une assertion de type et cela fonctionnera:

(project.assets as Asset[]).map((asset: Asset) => asset.id)

Cela ne vous permettra pas non plus d'affirmer son type comme c'est-à-dire number[] car TS vérifie toujours si votre assertion correspond à votre définition de type.

1
dziraf 19 juin 2019 à 15:59

Vous pouvez changer l'interface de Project en:

interface Project {
  assets: Array<string|Asset>;
}

Ou

interface Project<T> {
  assets: Array<T>;
}

const project: Project<Asset> = {
  assets: [
    {id: '1'}.
    {id: '2'},
    {id: '3'},
    {id: '4'}
  ],
};
project.assets.map((asset: Asset) => asset.id);
0
Lellansin 19 juin 2019 à 08:49

Je ne sais pas si c'est possible sans génériques, mais cela fonctionne au moins.

interface Project<T extends string | Asset> {
    assets: Array<T>;
}
const project: Project<Asset> = {
    assets: [
        {id: '1'},
        {id: '2'},
        {id: '3'},
        {id: '4'}
    ],
};
project.assets.map((asset) => {})
0
Niilo Keinänen 19 juin 2019 à 08:00