TypeScript
November 25, 2022(January 18, 2023更新)
React元件範例
const Header = ({ title }: { title: string }) => {
return <h1>{title}</h1>
}
<Header title="Hello" />
const Header = ({ children }: { children: ReactNode }): ReactElement => {
return <h1>{children}</h1>;
};
/* const fn = (a: a參數型態): fn回傳型態 => {} */
<Header>
<strong>Hello</strong>
</Header>
常見的React Type
-
FC
常見於Component回傳型態,FC<T>
定義Component回傳型態為FC<T>
,是一個FC(Function Component)可接受一個T型態的Props。import type { FC } from 'react' const MyComponent: FC<Props> => (props: Props) => { /* ... */ }
-
CSSProperties
當傳遞style做為Properties可以使用CSSProperties做為style的typeimport type { CSSProperties } from 'react'
types 邏輯運算
AND OR
type AType = {
a: number
}
type BType = {
b: number
}
type CType = AType & BType
// { a: number, b: nubmer }
type DType = AType | BType
// { a: number } or { b: number }
IF
在Typescript中用extends關鍵字來表示分支(if…else)
If<true, 'a', 'b'> // 'a'
If<false, 'a', 'b'> // 'b'
type If<C, T, F> = C extends true ? T : F;
// C是否是true,是的情況返回T, 否則返回F
Utility Types
Record
enum CATEGORY {
A = "a",
B = "b",
C = "c"
}
type ContentAll = Record<CATEGORY, string>;
// {a :string, b: string, c: string}
Pick
enum CATEGORY {
A = "a",
B = "b",
C = "c"
}
type ContentPick = Pick<ContentAll, CATEGORY.A | CATEGORY.C>
// {a: string, c: string}
-
Picker實作
type MyPick<T, K extends keyof T> = { [P in K]: T[P] }; /* Todo = { title: string completed: string } keyof Todo -> "title" | "completed" */
Omit
Omit<Type, Keys>
, 將Type中的Keys排除
interface Todo {
title: string;
description: string;
completed: boolean;
createdAt: number;
}
type TodoInfo = Omit<Todo, "completed" | "createdAt">;
// { title: string, description: string }
Readonly
Readonly<T>
,將type T 設定成唯讀屬性
type MyReadonly<T> = {
readonly [K in keyof T]: T[K]
}
PropertyKey
PropertyKey保留字,等同string | number | symbol
Infer
依靠TypeScript來判斷型態,必須使用在extends之後
extends是Typescript中分支的功能像是if…else
type Title<T> = T extends string ? string : unknown
-
Infer範例: 回傳Array第一筆元素型態
type First<T extends any[]> = T extends [infer U, ...any[]] ? U : never;
Exclude
Exclude<T, U> 在T中,但不在U中
type Exclude<T, U> = T extends U ? never : T;
/*
never是所有Type的子集合
type a = string | never // string
Exclude<"a" | "b" | "c", "c"> -> "a", "b"
"a" extends "c" -> "a"
"b" extends "c" -> "b"
"c" extends "c" -> never
*/
Awaited
Promise處理完後的返回型態
type X = Promise<string>
Awaited<X> // string
type Awaited<T> = T extends Promise<infer R> ?
(R extends Promise<unknown> ? Awaited<R> : R)
: never;
/*
先判斷T是不是Prmoise不是回傳never
判斷Promise裡面是不是還有Promise,是的話遞迴處理,否則回傳T
*/