Skip to main content

Type Assertions

รู้มั้ย Typescript สามารถหลอก Type ได้

TypeScript เป็นภาษาที่แยกตัวออกจากโลกของ JavaScript อย่างชัดเจน สิ่งที่ TypeScript พยายามทำคือ Type inference (คาดเดา) Type จากภาษา JavaScript. ดังนั้นเราเขียน TypeScript, แต่ ณ Runtime เราทำงานด้วย JavaScript.

แต่ในบางครั้งเรามักจะมีการใช้ any โดยตั้งใจ หรือไม่ตั้งใจ ก็ตาม แต่ any สามารถบังคับให้ Type เป็นอะไรก็ได้ผ่าน return type ของ function, as, หรือ satisfies

แนวทางการป้องกันความเข้าใจผิดเราอาจจะใช้ Eslint ที่ชื่อ @typescript-eslint/no-unsafe-return

แต่อย่างไรก็ตาม ถ้าเราใช้ as หรือ satisfies เป็นการใช้ บังคับเปลี่ยน type ของ any โดยตั้งใจ TypeScript ถือว่า เรารับทราบปัญหาที่จะเกิดขึ้นในอนาคต

หมายเหตุ: as หรือ satisfies มีประโยชน์ในหลายๆ เหตุการณ์ เลือกใช้ตามความเหมาะสม

ตัวอย่างการใช้ Fetch ที่อาจจะนำมาซึ่งปัญหา

interface Person {
data: {
name: string;
};
}
const url = "https://jsonplaceholder.typicode.com/todos/1";
async function getUserData1(): Promise<Person> {
const result = (await fetch(url)).json();
// ^? Promise<any>
return result;
}

async function getUserData2(){
const result = (await fetch(url)).json();
// ^? Promise<any>
return result as Promise<Person>; // Same as `satisfies Promise<Person>`
}

/**
* ไม่ได้ Error, ใน TypeScript, แต่ ❌ Error ที่ Runtime, TypeError: Cannot read properties of undefined (reading 'name')
**/
console.log((await getUserData1()).data.name);
console.log((await getUserData2()).data.name);

export {};

ลองเล่น Playground

Const Assertions

เราสามารถแปลง Object เป็น Readonly ผ่าน as const

const assertions in Typescript https://mainawycliffe.dev/blog/const-assertion-in-typescript/

const person = {
name: "John Doe",
age: 25,
};

const person = {
name: "John Doe",
age: 25,
} as const;

// (Note: This is not TypeScript Syntax)
// const person: {
// readonly name: "John Doe";
// readonly age: 25;
// }