TypeScript: การอนุมานประเภทเมื่อใช้สตริงลิตเทอรัล
กรุณาดูโค้ด TypeScript ต่อไปนี้ จะเห็นได้ชัดว่าการอนุมานประเภททำงานตามที่อธิบายไว้ในคอมเมนต์
ตอนนี้คำถามคือ: เป็นไปได้ไหมที่จะเปลี่ยนคำนิยามของ type V2=... ในลักษณะที่มันสรุปเป็นประเภท "someOtherValue" และไม่ใช่ string โดยทั่วไปอีกต่อไป?
เท่าที่ฉันเข้าใจการอนุมานประเภทของ TypeScript นี่เป็นไปไม่ได้อย่างแน่นอน ... แต่ใครจะรู้ บางทีฉันอาจจะผิด เพื่อความปลอดภัย ฉันควรถามชุมชน TypeScript เพื่อขอความช่วยเหลือ ขอบคุณ
const config1 = { value: 'someValue' as const }
type K1 = keyof typeof config1 // type K1: "value" (not string in general)
type V1 = (typeof config1)['value'] // type V1: "someValue" (not string in general)
const config2 = { value: 'someOtherValue' }
type K2 = keyof typeof config2 // type K2: "value" (not string in general)
type V2 = (typeof config2)['value'] // type V2: string
TypeScript Playground: ตัวอย่าง
คำตอบ #1
คุณต้องแคสต์ const กับทั้ง config2 ด้วยเช่นกัน
const config2 = { value: 'someOtherValue' } as const;
มิฉะนั้นมันก็จะเป็นสตริงเสมอ
ด้วยการเข้าถึงด้วยกุญแจ
const config1 = { value: 'someValue' as const }
type K1 = keyof typeof config1 // type K1: "value" (not string in general)
type V1 = (typeof config1)['value'] // type V1: "someValue" (not string in general)
const config2 = { value: 'someOtherValue' } as const;
type K2 = keyof typeof config2 // type K2: "value" (not string in general)
type V2 = (typeof config2)[K2] // type V2: "someOtherValue"
คำตอบ #2
ตอนนี้คำถาม: จะเป็นไปได้ไหมที่จะเปลี่ยนคำจำกัดความของ type V2=... ในลักษณะที่มันสรุปว่าเป็น type "someOtherValue" และไม่ใช่ string โดยทั่วไปอีกต่อไป?
ใช่ คุณต้องบอก TypeScript ว่าประเภทจะไม่เปลี่ยนแปลงด้วยการยืนยัน const คุณสามารถนำไปใช้กับ prop value หรือทั้งวัตถุได้ตามที่ @satanTime แนะนำ
ทำไม? เพราะ TypeScript สมมติว่าคุณอาจทำสิ่งต่อไปนี้
const config2 = { value: 'someOtherValue' }
config2.value = "something different"
ด้วยการใช้การยืนยันค่า const ตัวตรวจสอบชนิดสามารถตัดสินใจทำการจำกัดชนิดได้
const config1 = { value: 'someValue' as const }
config1.value = "test" // Type '"test"' is not assignable to type '"someValue"'.
const config2 = { value: 'someOtherValue' } as const
config2.value = "test" // Cannot assign to 'value' because it is a read-only property.
