Utilizzo del simbolo come tipo di chiave oggetto in TypeScript


20

Sto cercando di definire un oggetto con un simbolo come tipo di chiave poiché MDN dice:

Un valore di simbolo può essere utilizzato come identificatore per le proprietà degli oggetti [...]

Ma usandolo come tipo per la proprietà-chiave:

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

provoca il seguente errore:

TS1023: Un tipo di parametro di firma indice deve essere 'stringa' o 'numero'.

anche può essere usato come tipo di indice. Sto usando l'ultima versione di dattiloscritto ( v3.7.2), domande correlate che ho trovato:

Ho anche dato un'occhiata ai documenti dei simboli dattiloscritti, ma mostrano solo come viene usato come valore, non come tipo.

Esempio:

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

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

Problema su Microsoft / TypeScript

Apri richiesta funzionalità


Penso che TypeScript supporti solo simboli specifici nelle sue dichiarazioni del tipo di oggetto. Vuoi davvero qualsiasi symbol ? Magari mostra un esempio di come vuoi usare il tuo type obj- Dubito che tutte le proprietà con chiave di simbolo saranno strings.
Bergi,

@Bergi Ho aggiunto un esempio, forse ho supervisionato qualcosa ma non riesco a trovare un modo per indurre ts ad accettare un simbolo (senza usare anyquale è una cattiva pratica).
Simon,


non sono sicuro di aver ragione, ma hai provato a usare Map<Symbol,String>come abbiamo Map, se questo avrebbe avuto lo scopo di quello che stai cercando di ottenere
pavan kumar

Lo stesso problema per me, immagino che la parte fastidiosa sia la falsa pubblicità di come "TS è un superset di JS" - beh, non esattamente. questo è un esempio perfetto di ciò.
Patrick

Risposte:


3

Purtroppo questo non è possibile al momento in TypeScript. Se devi interagire con alcune API che si aspettano questo o vogliono davvero usare i simboli come chiavi, puoi fare questa versione scomoda:

// 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.