typescript array.map สูญเสียประเภทที่ส่งกลับ
ฉันคาดว่าจะมีข้อผิดพลาดประเภทในโค้ดต่อไปนี้ แต่สำหรับ TypeScript มันใช้ได้อย่างสมบูรณ์ คุณบอกฉันได้ไหมว่าทำไม?
export interface Structure {
aaa: string;
}
export function f1(): Structure[] { // OK for typescript, not for me
const result = [].map(certState => {
return {
aaa: 'aaa',
ADDITIONAL_FIELD: 'asdf'
}
});
return result;
}
export function f2(): Structure[] { // ERROR for typescript (and for me)
return [
{
aaa: 'sdf',
ADDITIONAL_FIELD: 'asdf'
}
]
}
นี่คือลิงก์
ขอบคุณ!
คำตอบ #1
ข้อผิดพลาดเกิดจากข้อเท็จจริงที่ว่าใน f2() คุณกำลังส่งค่าผลลัพธ์ของคุณโดยตรง
ถ้าคุณเปลี่ยน f2() ให้เป็น
export function f2(): Structure[] {
const returnVal = [
{
aaa: 'sdf',
ADDITIONAL_FIELD: 'asdf'
}
]
return returnVal;
}
แล้วจะไม่มีข้อผิดพลาดของคอมไพเลอร์
TypeScript ใช้การพิมพ์เชิงโครงสร้างเพื่อกำหนดความเข้ากันได้ของชนิด ดังนั้นในโค้ดของคุณสำหรับ f1(), result เป็นชนิด
{
aaa: string,
ADDITIONAL_FIELD: string
}[]
ซึ่งเข้ากันได้กับ Structure[] (ไม่มีอันตรายในเรื่องการจำกัดประเภท)
ฉันไม่แน่ใจ 100% ว่าทำไมการคืนค่าโดยตรงถึงใช้ไม่ได้ แต่สมมติฐานของฉันคือใน f2() คุณกำลังบอกคอมไพเลอร์ว่า "อาเรย์เฉพาะนี้เป็นชนิด Structure[]" และมันก็บอกว่าไม่ใช่ เมื่อคุณมีตัวแปรกลางใน f1() คุณกำลังบอกว่า "ฟังก์ชันนี้คืนค่า Structure[]" และเมื่อคุณคืนค่าตัวแปรกลาง คอมไพเลอร์จะตรวจสอบและบอกว่า "โอเค result ตรงกับ Structure[]" ดังนั้นฟังก์ชันนี้จึงทำงานตามที่มันบอก.
ฉันอยากรู้ว่าคนอื่นมีคำอธิบายที่ละเอียดกว่านี้หรือไม่
คำตอบ #2
ฉันเพิ่งเรียนรู้ว่า Typescript มีแนวคิดของประเภทที่แน่นอนเฉพาะสำหรับวัตถุ literal ดังนั้น f1 จึงไม่ได้ใช้วัตถุ literal ดังนั้นคุณสมบัติที่เพิ่มเข้ามาไม่สามารถเพิ่มได้และถือว่าเป็นไปตาม Typescript f2 ใช้วัตถุ literal ดังนั้นคุณสมบัติที่เพิ่มเข้ามาจะไม่อนุญาต สิ่งนี้ทำให้ฉันกลัวมาก แต่ก็เป็นวิธีการทำงานของ Typescript
