การจัดการชนิดข้อมูล
การสร้างชนิดจากชนิดอื่น
คุณสามารถสร้างชนิดใหม่ได้ด้วยการประกอบ จัดการ หรือแปลงชนิดที่มีอยู่
ชนิด Intersection (&):
ช่วยให้คุณรวมหลายชนิดเป็นชนิดเดียวได้:
type A = { foo: number };type B = { bar: string };type C = A & B; // Intersection of A and Bconst obj: C = { foo: 42, bar: 'hello' };ชนิด Union (|):
ช่วยให้คุณกำหนดชนิดที่สามารถเป็นหนึ่งในหลายชนิดได้:
type Result = string | number;const value1: Result = 'hello';const value2: Result = 42;ชนิด Mapped:
ช่วยให้คุณแปลงพร็อพเพอร์ตีของชนิดที่มีอยู่เพื่อสร้างชนิดใหม่ได้:
type Mutable<T> = { readonly [P in keyof T]: T[P];};type Person = { name: string; age: number;};type ImmutablePerson = Mutable<Person>; // Properties become read-onlyชนิด Conditional:
ช่วยให้คุณสร้างชนิดตามเงื่อนไขบางอย่างได้:
type ExtractParam<T> = T extends (param: infer P) => any ? P : never;type MyFunction = (name: string) => number;type ParamType = ExtractParam<MyFunction>; // stringชนิด Indexed Access
ใน TypeScript คุณสามารถเข้าถึงและจัดการชนิดของพร็อพเพอร์ตีภายในอีกชนิดหนึ่งได้โดยใช้ดัชนี Type[Key]
type Person = { name: string; age: number;};
type AgeType = Person['age']; // numbertype MyTuple = [string, number, boolean];type MyType = MyTuple[2]; // booleanUtility Type
Utility type ในตัวหลายรายการสามารถใช้จัดการชนิดข้อมูลได้ ด้านล่างคือรายการที่ใช้บ่อยที่สุด:
Awaited<T>
สร้างชนิดที่แกะชนิด Promise ซ้ำแบบ recursive
type A = Awaited<Promise<string>>; // stringPartial<T>
สร้างชนิดที่กำหนดให้พร็อพเพอร์ตีทั้งหมดของ T เป็นแบบเลือกได้
type Person = { name: string; age: number;};
type A = Partial<Person>; // { name?: string | undefined; age?: number | undefined; }Required<T>
สร้างชนิดที่กำหนดให้พร็อพเพอร์ตีทั้งหมดของ T เป็นแบบบังคับ
type Person = { name?: string; age?: number;};
type A = Required<Person>; // { name: string; age: number; }Readonly<T>
สร้างชนิดที่กำหนดให้พร็อพเพอร์ตีทั้งหมดของ T เป็น readonly
type Person = { name: string; age: number;};
type A = Readonly<Person>;
const a: A = { name: 'Simon', age: 17 };a.name = 'John'; // InvalidRecord<K, T>
สร้างชนิดที่มีชุดพร็อพเพอร์ตี K ซึ่งมีชนิดเป็น T
type Product = { name: string; price: number;};
const products: Record<string, Product> = { apple: { name: 'Apple', price: 0.5 }, banana: { name: 'Banana', price: 0.25 },};
console.log(products.apple); // { name: 'Apple', price: 0.5 }Pick<T, K>
สร้างชนิดด้วยการเลือกพร็อพเพอร์ตี K ที่ระบุจาก T
type Product = { name: string; price: number;};
type Price = Pick<Product, 'price'>; // { price: number; }Omit<T, K>
สร้างชนิดด้วยการละเว้นพร็อพเพอร์ตี K ที่ระบุจาก T
type Product = { name: string; price: number;};
type Name = Omit<Product, 'price'>; // { name: string; }Exclude<T, U>
สร้างชนิดด้วยการตัดค่าทั้งหมดของชนิด U ออกจาก T
type Union = 'a' | 'b' | 'c';type MyType = Exclude<Union, 'a' | 'c'>; // bExtract<T, U>
สร้างชนิดด้วยการดึงค่าทั้งหมดของชนิด U จาก T
type Union = 'a' | 'b' | 'c';type MyType = Extract<Union, 'a' | 'c'>; // a | cNonNullable<T>
สร้างชนิดด้วยการตัด null และ undefined ออกจาก T
type Union = 'a' | null | undefined | 'b';type MyType = NonNullable<Union>; // 'a' | 'b'Parameters<T>
ดึงชนิดพารามิเตอร์ของฟังก์ชันชนิด T
type Func = (a: string, b: number) => void;type MyType = Parameters<Func>; // [a: string, b: number]ConstructorParameters<T>
ดึงชนิดพารามิเตอร์ของฟังก์ชันคอนสตรักเตอร์ชนิด T
class Person { constructor( public name: string, public age: number ) {}}type PersonConstructorParams = ConstructorParameters<typeof Person>; // [name: string, age: number]const params: PersonConstructorParams = ['John', 30];const person = new Person(...params);console.log(person); // Person { name: 'John', age: 30 }ReturnType<T>
ดึงชนิดค่าที่ส่งคืนของฟังก์ชันชนิด T
type Func = (name: string) => number;type MyType = ReturnType<Func>; // numberInstanceType<T>
ดึงชนิดอินสแตนซ์ของคลาสชนิด T
class Person { name: string;
constructor(name: string) { this.name = name; }
sayHello() { console.log(`Hello, my name is ${this.name}!`); }}
type PersonInstance = InstanceType<typeof Person>;
const person: PersonInstance = new Person('John');
person.sayHello(); // Hello, my name is John!ThisParameterType<T>
ดึงชนิดของพารามิเตอร์ ‘this’ จากฟังก์ชันชนิด T
interface Person { name: string; greet(this: Person): void;}type PersonThisType = ThisParameterType<Person['greet']>; // PersonOmitThisParameter<T>
ลบพารามิเตอร์ ‘this’ ออกจากฟังก์ชันชนิด T
function capitalize(this: String) { return this[0].toUpperCase() + this.substring(1).toLowerCase();}
type CapitalizeType = OmitThisParameter<typeof capitalize>; // () => stringThisType<T>
ทำหน้าที่เป็นตัวระบุสำหรับชนิด this ตามบริบท
type Logger = { log: (error: string) => void;};
let helperFunctions: { [name: string]: Function } & ThisType<Logger> = { hello: function () { this.log('some error'); // Valid as "log" is a part of "this". this.update(); // Invalid },};Uppercase<T>
เปลี่ยนชื่อของชนิดอินพุต T ให้เป็นตัวพิมพ์ใหญ่
type MyType = Uppercase<'abc'>; // "ABC"Lowercase<T>
เปลี่ยนชื่อของชนิดอินพุต T ให้เป็นตัวพิมพ์เล็ก
type MyType = Lowercase<'ABC'>; // "abc"Capitalize<T>
เปลี่ยนอักษรตัวแรกของชื่อชนิดอินพุต T ให้เป็นตัวพิมพ์ใหญ่
type MyType = Capitalize<'abc'>; // "Abc"Uncapitalize<T>
เปลี่ยนอักษรตัวแรกของชื่อชนิดอินพุต T ให้เป็นตัวพิมพ์เล็ก
type MyType = Uncapitalize<'Abc'>; // "abc"NoInfer<T>
NoInfer เป็น utility type ที่ออกแบบมาเพื่อป้องกันการอนุมานชนิดโดยอัตโนมัติภายในขอบเขตของฟังก์ชัน generic
ตัวอย่าง:
// Automatic inference of types within the scope of a generic function.function fn<T extends string>(x: T[], y: T) { return x.concat(y);}const r = fn(['a', 'b'], 'c'); // Type here is ("a" | "b" | "c")[]เมื่อใช้ NoInfer:
// Example function that uses NoInfer to prevent type inferencefunction fn2<T extends string>(x: T[], y: NoInfer<T>) { return x.concat(y);}
const r2 = fn2(['a', 'b'], 'c'); // Error: Type Argument of type '"c"' is not assignable to parameter of type '"a" | "b"'.