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

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