ค้นหาเว็บไซต์

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.