web-dev-qa-db-fra.com

Utilisation du symbole comme type de clé d'objet dans TypeScript

J'essaie de définir un objet avec un symbole comme type de clé depuis MDN dit:

Une valeur de symbole peut être utilisée comme identifiant pour les propriétés des objets [...]

Mais en l'utilisant comme type pour la propriété clé:

type obj = {
    [key: symbol | string]: string
}

entraîne l'erreur suivante:

TS1023: Un type de paramètre de signature d'index doit être "chaîne" ou "nombre".

même peut être utilisé comme type d'index. J'utilise la dernière version de TypeScript (v3.7.2), questions connexes que j'ai trouvées:

J'ai également jeté un coup d'œil aux documentation des symboles TypeScript mais ils montrent seulement comment il est utilisé comme valeur, pas comme type.

Exemple:

const obj = {} as {
    [key: number | symbol]: string // Won't work
};

const sym = Symbol('My symbol');
obj[sym] = 'Hi';

Problème sur Microsoft/TypeScript

Ouvrir la demande de fonctionnalité

19
Simon

Malheureusement, cela n'est pas possible pour le moment en TypeScript. Si vous devez interagir avec certaines API qui attendent cela ou vraiment vouloir utiliser des symboles comme clés, vous pouvez faire cette version maladroite:

// Ensure we can not pass regular map to our custom functions
type SymbolMapTag = { readonly symbol: unique symbol }

type SymbolMap = SymbolMapTag & {
    [Key in string | number | symbol]: string;
}

function set_symbol<T extends SymbolMap, TSym extends symbol>
(target: T, sym: TSym, value: T[TSym]) {
    target[sym] = value;
}

function get_symbol<T extends SymbolMap, TSym extends symbol>
(target: T, sym: TSym): T[TSym] {
    return target[sym];
}

const symbol_map = {} as SymbolMap;

const sym = Symbol('My symbol');
set_symbol(symbol_map, sym, "hi");
get_symbol(symbol_map, sym); // string


type NonSymbolMap = {
    [Key in string | number]: string;
}

const non_symbol_map = {} as NonSymbolMap;
set_symbol(non_symbol_map, sym, "hi"); // error
get_symbol(non_symbol_map, sym); // error
2
Dmitriy