Menggunakan simbol sebagai tipe objek-kunci dalam TypeScript


20

Saya mencoba mendefinisikan objek dengan simbol sebagai tipe kunci sejak MDN mengatakan:

Nilai simbol dapat digunakan sebagai pengidentifikasi untuk properti objek [...]

Tetapi menggunakannya sebagai tipe untuk properti-kunci:

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

mengakibatkan kesalahan berikut:

TS1023: Jenis parameter tanda tangan indeks harus berupa 'string' atau 'angka'.

bahkan dapat digunakan sebagai tipe indeks. Saya menggunakan versi naskah terbaru ( v3.7.2), pertanyaan terkait yang saya temukan:

Saya juga telah melihat dokumen simbol naskah tetapi mereka hanya menunjukkan bagaimana itu digunakan sebagai nilai, bukan sebagai jenis.

Contoh:

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

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

Masalah pada Microsoft / TypeScript

Buka permintaan fitur


Saya pikir TypeScript hanya mendukung simbol spesifik dalam deklarasi tipe objeknya. Apakah Anda benar-benar ingin setiap symbol ? Mungkin tunjukkan contoh bagaimana Anda ingin menggunakan milik Anda type obj- Saya ragu bahwa semua properti dengan kunci simbol adalah strings.
— Bergi

@Bergi Saya telah menambahkan contoh, mungkin saya telah mengawasi sesuatu tetapi saya tidak dapat menemukan cara untuk membawa ts menerima simbol (tanpa menggunakan anyyang merupakan praktik buruk).
— Simon


Saya tidak yakin apakah saya benar tetapi apakah Anda mencoba menggunakan Map<Symbol,String>karena kami memiliki Peta, jika itu akan melayani tujuan dari apa yang Anda coba capai
— pavan kumar

Masalah yang sama bagi saya, saya kira bagian yang mengganggu adalah iklan palsu tentang bagaimana "TS adalah superset dari JS" - well, tidak persis. ini adalah contoh sempurna untuk itu.
— Patrick

Jawaban:


3

Sayangnya ini tidak mungkin saat ini dalam TypeScript. Jika Anda harus beroperasi dengan beberapa API yang mengharapkan ini atau benar - benar ingin menggunakan simbol sebagai kunci, Anda dapat melakukan versi canggung ini:

// 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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.