Skip to 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 ที่อาจจะนำมาซึ่งปัญหา

ts
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/

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;
// }