การใช้สัญลักษณ์เป็นประเภทวัตถุคีย์ใน TypeScript


20

ฉันกำลังพยายามกำหนดวัตถุที่มีสัญลักษณ์เป็นชนิดคีย์เนื่องจาก MDN พูดว่า:

ค่าสัญลักษณ์อาจใช้เป็นตัวระบุสำหรับคุณสมบัติของวัตถุ [... ]

แต่ใช้เป็นชนิดสำหรับคุณสมบัติคีย์:

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

ผลลัพธ์ในข้อผิดพลาดต่อไปนี้:

TS1023: ชนิดพารามิเตอร์ดัชนีลายเซ็นต้องเป็น 'สตริง' หรือ 'หมายเลข'

แม้จะสามารถใช้เป็นดัชนีชนิด ฉันใช้รุ่น typescript ล่าสุด ( v3.7.2) คำถามที่เกี่ยวข้องที่ฉันพบ:

ฉันได้ดูที่เอกสารสัญลักษณ์ typescriptแต่พวกเขาก็แสดงให้เห็นว่ามันถูกใช้เป็นค่าอย่างไรไม่ใช่ประเภท

ตัวอย่าง:

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

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

ปัญหาเกี่ยวกับ Microsoft / TypeScript

เปิดคำขอคุณสมบัติ


ฉันคิดว่า TypeScript รองรับสัญลักษณ์เฉพาะในการประกาศประเภทของวัตถุ คุณต้องการอะไร จริงๆsymbolเหรอ? อาจแสดงตัวอย่างว่าคุณต้องการใช้งานอย่างไรtype obj- ฉันสงสัยว่าคุณสมบัติที่เป็นสัญลักษณ์สัญลักษณ์ทั้งหมดจะเป็นstrings
Bergi

@Bergi ฉันได้เพิ่มตัวอย่างบางทีฉันอาจจะดูแลบางอย่าง แต่ฉันไม่สามารถหาวิธีที่จะนำ ts เพื่อรับสัญลักษณ์ (โดยไม่ต้องใช้anyซึ่งเป็นการฝึกฝนที่ไม่ดี)
Simon


ไม่แน่ใจว่าถูกต้องหรือไม่ แต่คุณลองใช้Map<Symbol,String>ในขณะที่เรามีแผนที่ถ้านั่นจะให้บริการตามวัตถุประสงค์ของสิ่งที่คุณพยายามที่จะบรรลุ
pavan kumar

ปัญหาเดียวกันสำหรับฉันฉันเดาว่าส่วนที่น่ารำคาญคือโฆษณาเท็จว่า "TS เป็น superset ของ JS" อย่างไร - ก็ไม่เชิง นี่เป็นตัวอย่างที่สมบูรณ์แบบของสิ่งนั้น
Patrick

คำตอบ:


3

น่าเสียดายที่สิ่งนี้ไม่สามารถทำได้ใน TypeScript ในขณะนี้ หากคุณมีการทำงานร่วมกับ APIs บางอย่างที่คาดหวังนี้หรือจริงๆต้องการที่จะใช้สัญลักษณ์เป็นกุญแจที่คุณสามารถทำรุ่นที่น่าอึดอัดใจนี้:

// 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.