高階TypeScript型別備忘單(帶示例)
https://dev.to/ibrahima92/advanced-typescript-types-cheat-sheet-with-examples-5414 轉載
1 交集型別
是一種將多種型別組合為一種型別的方法。這意味著您可以將給定的型別a與型別B或更多合併,並獲得具有所有屬性的單一型別。
type LeftType = {
id: number
left: string
}
type RightType = {
id: number
right: string
}
type IntersectionType = LeftType & RightType
function showType(args: IntersectionType) {
console.log(args)
}
showType({ id: 1, left: "test", right: "test" })
// Output: {id: 1, left: "test", right: "test"}
如您所見,IntersectionType結合了兩種型別——LeftType和RightType,並使用&符號來構造交集型別。
2 聯合型別 允許在給定變數中擁有不同的型別註釋。
type UnionType = string | number
function showType(arg: UnionType) {
console.log(arg)
}
showType("test")
// Output: test
showType(7)
函式showType是一個聯合型別,接受字串和數字作為引數
3 泛型型別 是重用給定型別的一部分的一種方式。它有助於捕獲作為引數傳入的型別T。
function showType<T>(args: T) {
console.log(args)
}
showType("test")
// Output: "test"
showType(1)
// Output: 1
要構造泛型型別,需要使用方括號並將T作為引數傳遞。
這裡,我使用T(名稱由您決定),然後使用不同的型別註釋呼叫函式showType兩次,因為它是泛型的——它可以重用。
interface GenericType<T> {
id: number
name: T
}
function showType(args: GenericType<string>) {
console.log(args)
}
showType({ id: 1, name: "test" })
// Output: {id: 1, name: "test"}
function showTypeTwo(args: GenericType<number>) {
console.log(args)
}
showTypeTwo({ id: 1, name: 4 })
// Output: {id: 1, name: 4}
這裡,我們有另一個例子,它有一個介面GenericType,它接收一個泛型型別t。由於它是可重用的,我們可以先用一個字串,然後用一個數字來呼叫它
interface GenericType<T, U> {
id: T
name: U
}
function showType(args: GenericType<number, string>) {
console.log(args)
}
showType({ id: 1, name: "test" })
// Output: {id: 1, name: "test"}
function showTypeTwo(args: GenericType<string, string[]>) {
console.log(args)
}
showTypeTwo({ id: "001", name: ["This", "is", "a", "Test"] })
// Output: {id: "001", name: Array["This", "is", "a", "Test"]}
泛型型別可以接收多個引數。這裡,我們傳入兩個引數:T和U,然後將它們用作屬性的型別註釋。也就是說,我們現在可以使用介面並提供不同的型別作為引數。
4實用程式類
TypeScript提供了方便的內建工具,幫助您輕鬆地操作型別。要使用它們,您需要將要轉換的型別傳遞給<>。
部分< T >
Partial允許您使型別T的所有屬性都是可選的。它會新增a ?在每個欄位旁邊標記。
interface PartialType {
id: number
firstName: string
lastName: string
}
function showType(args: Partial<PartialType>) {
console.log(args)
}
showType({ id: 1 })
// Output: {id: 1}
showType({ firstName: "John", lastName: "Doe" })
// Output: {firstName: "John", lastName: "Doe"}
如您所見,我們有一個介面PartialType,它被用作showType()函式接收的引數的型別註釋。為了使屬性可選,我們必須使用Partial關鍵字並傳入型別PartialType作為引數。也就是說,現在所有欄位都是可選的。
5 要求需要< T >
與Partial不同,Required實用程式生成型別T的所有屬性。
id: number
firstName?: string
lastName?: string
}
function showType(args: Required<RequiredType>) {
console.log(args)
}
showType({ id: 1, firstName: "John", lastName: "Doe" })
// Output: { id: 1, firstName: "John", lastName: "Doe" }
showType({ id: 1 })
// Error: Type '{ id: number: }' is missing the following properties from type 'Required<RequiredType>': firstName, lastName
Required實用程式將使所有屬性都成為必需的,即使我們在使用實用程式之前先將它們設定為可選的。如果省略了某個屬性,TypeScript會丟擲一個錯誤。
6 只讀的< T >
這個實用程式型別將轉換型別T的所有屬性,以使它們不能用新值重新分配。
interface ReadonlyType {
id: number
name: string
}
function showType(args: Readonly<ReadonlyType>) {
args.id = 4
console.log(args)
}
showType({ id: 1, name: "Doe" })
// Error: Cannot assign to 'id' because it is a read-only property.
這裡,我們使用實用程式Readonly使ReadonlyType的屬性不可重新分配。也就是說,如果您試圖給這些欄位中的一個新值,就會丟擲一個錯誤。
除此之外,您還可以在屬性前使用關鍵字readonly,使其不可重新分配。
interface ReadonlyType {
readonly id: number
name: string
}
7選擇< T, K >
它允許您通過選擇現有模型T的一些屬性K來建立新型別。
interface PickType {
id: number
firstName: string
lastName: string
}
function showType(args: Pick<PickType, "firstName" | "lastName">) {
console.log(args)
}
showType({ firstName: "John", lastName: "Doe" })
// Output: {firstName: "John"}
showType({ id: 3 })
// Error: Object literal may only specify known properties, and 'id' does not exist in type 'Pick<PickType, "firstName" | "lastName">'
Pick與我們已經看到的前面的實用程式有一點不同。它需要兩個引數——T是您想要從中選擇元素的型別,K是您想要選擇的屬性。您還可以通過使用管道(|)符號將它們分開來選擇多個欄位。
8省略< T, K >
省略實用程式與Pick型別相反。它將從型別T中刪除K個屬性,而不是選擇元素。
interface PickType {
id: number
firstName: string
lastName: string
}
function showType(args: Omit<PickType, "firstName" | "lastName">) {
console.log(args)
}
showType({ id: 7 })
// Output: {id: 7}
showType({ firstName: "John" })
// Error: Object literal may only specify known properties, and 'firstName' does not exist in type 'Pick<PickType, "id">'
這個實用程式類似於Pick的工作方式。它期望型別和屬性從該型別中省略。
8提取< T U >
Extract允許您通過選擇兩種不同型別的屬性來構造型別。該實用程式將提取從T所有的屬性,是分配給U。
interface FirstType {
id: number
firstName: string
lastName: string
}
interface SecondType {
id: number
address: string
city: string
}
type ExtractType = Extract<keyof FirstType, keyof SecondType>
// Output: "id"
在這裡,我們有兩種型別的共同屬性id。因此,通過使用Extract關鍵字,我們得到欄位id,因為它在兩個介面中都存在。如果您有多個共享欄位,該實用程式將提取所有類似的屬性。
9 排除
與Extract不同,Exclude實用程式將通過排除已經存在於兩種不同型別中的屬性來構造型別。它排除了所有可分配給U的欄位。
interface FirstType {
id: number
firstName: string
lastName: string
}
interface SecondType {
id: number
address: string
city: string
}
type ExcludeType = Exclude<keyof FirstType, keyof SecondType>
// Output; "firstName" | "lastName"
正如您在這裡看到的,屬性firstName和lastName可分配給SecondType型別,因為它們不存在。通過使用Extract關鍵字,我們將按預期獲得這些欄位。
10 記錄< K, T >
這個實用程式幫助您構造一個具有一組給定型別t的屬性K的型別。當需要將一個型別的屬性對映到另一個型別時,Record非常方便。
interface EmployeeType {
id: number
fullname: string
role: string
}
let employees: Record<number, EmployeeType> = {
0: { id: 1, fullname: "John Doe", role: "Designer" },
1: { id: 2, fullname: "Ibrahima Fall", role: "Developer" },
2: { id: 3, fullname: "Sara Duckson", role: "Developer" },
}
// 0: { id: 1, fullname: "John Doe", role: "Designer" },
// 1: { id: 2, fullname: "Ibrahima Fall", role: "Developer" },
// 2: { id: 3, fullname: "Sara Duckson", role: "Developer" }
Record的工作方式相對簡單。這裡,它期望一個數字作為型別,這就是為什麼我們將0、1和2作為employees變數的鍵。如果嘗試使用字串作為屬性,則會丟擲錯誤。接下來,屬性集由EmployeeType給出,因此物件包含欄位id、fullName和role。
11 NonNullable < T >
它允許您從型別T中刪除null和undefined。
type NonNullableType = string | number | null | undefined
function showType(args: NonNullable<NonNullableType>) {
console.log(args)
}
showType("test")
// Output: "test"
showType(1)
// Output: 1
showType(null)
// Error: Argument of type 'null' is not assignable to parameter of type 'string | number'.
showType(undefined)
// Error: Argument of type 'undefined' is not assignable to parameter of type 'string | number'.
這裡,我們將型別NonNullableType作為引數傳遞給NonNullable實用程式,該實用程式通過從該型別中排除null和undefined來構造一個新型別。也就是說,如果你傳遞一個可為空的值,TypeScript會丟擲一個錯誤。
順便說一下,如果你在tsconfig檔案中新增——strictNullChecks標誌,TypeScript會應用非空性規則。
12 對映型別
對映型別允許您獲取一個現有的模型,並將其每個屬性轉換為一個新型別。注意,前面介紹的一些實用程式型別也是對映型別。
type StringMap<T> = {
[P in keyof T]: string
}
function showType(arg: StringMap<{ id: number; name: string }>) {
console.log(arg)
}
showType({ id: 1, name: "Test" })
// Error: Type 'number' is not assignable to type 'string'.
showType({ id: "testId", name: "This is a Test" })
// Output: {id: "testId", name: "This is a Test"}
StringMap<>將把傳入的任何型別轉換為字串。也就是說,如果我們在函式showType()中使用它,接收到的引數必須是一個字串——否則,TypeScript將丟擲一個錯誤。
13 型別警衛 型別保護允許您使用操作符檢查變數或物件的型別。它是一個條件塊,使用typeof、instanceof或in返回型別
typeof
function showType(x: number | string) {
if (typeof x === "number") {
return `The result is ${x + x}`
}
throw new Error(`This operation can't be done on a ${typeof x}`)
}
showType("I'm not a number")
// Error: This operation can't be done on a string
showType(7)
// Output: The result is 14
如您所見,我們有一個普通的JavaScript條件塊,它檢查typeof接收到的引數的型別。有了這些之後,您現在可以用這個條件來保護您的型別。
instanceof
class Foo {
bar() {
return "Hello World"
}
}
class Bar {
baz = "123"
}
function showType(arg: Foo | Bar) {
if (arg instanceof Foo) {
console.log(arg.bar())
return arg.bar()
}
throw new Error("The type is not supported")
}
showType(new Foo())
// Output: Hello World
showType(new Bar())
// Error: The type is not supported
與前面的示例一樣,這個示例也是一個型別保護,它檢查接收到的引數是否是Foo類的一部分,然後對其進行處理。
in
interface FirstType {
x: number
}
interface SecondType {
y: string
}
function showType(arg: FirstType | SecondType) {
if ("x" in arg) {
console.log(`The property ${arg.x} exists`)
return `The property ${arg.x} exists`
}
throw new Error("This type is not expected")
}
showType({ x: 7 })
// Output: The property 7 exists
showType({ y: "ccc" })
// Error: This type is not expected
in操作符允許您檢查作為引數接收的物件上是否存在屬性x。
14 有條件的型別 它測試兩種型別,並根據測試結果選擇其中一種。
type NonNullable<T> = T extends null | undefined ? never : T
這個非空實用程式型別的例子檢查型別是否為空,並根據它來處理。正如您所注意到的,它使用JavaScript三元操作符。
相關文章
- Typescript高階型別TypeScript型別
- TypeScript筆記(二)高階型別TypeScript筆記型別
- 13 個Typescript 實用型別:開發人員的備忘單TypeScript型別
- Javascript高階程式設計 備忘JavaScript程式設計
- 為 Vue3 學點 TypeScript, 解讀高階型別VueTypeScript型別
- 為vue3學點typescript, 基礎型別和入門高階型別VueTypeScript型別
- Java備忘錄《資料型別》Java資料型別
- TypeScript 中高階型別的理解?有哪些?TypeScript型別
- Cats(三):高階型別型別
- TypeScript this型別TypeScript型別
- Typescript 高階語法進階TypeScript
- 簡單探討TypeScript 列舉型別TypeScript型別
- TypeScript 泛型型別TypeScript泛型型別
- TypeScript 型別相容TypeScript型別
- TypeScript 交叉型別TypeScript型別
- Typescript:基本型別TypeScript型別
- TypeScript 字串型別TypeScript字串型別
- TypeScript Never型別TypeScript型別
- TypeScript Any型別TypeScript型別
- TypeScript 索引型別TypeScript索引型別
- TypeScript 型別安全TypeScript型別
- TypeScript type 型別別名TypeScript型別
- 【Scala之旅】特質與高階型別型別
- redis-22.高階資料型別Redis資料型別
- Redis 高階資料型別重溫Redis資料型別
- C++/C高階資料型別C++資料型別
- TypeScript 型別系統TypeScript型別
- TypeScript 聯合型別TypeScript型別
- TypeScript 型別保護TypeScript型別
- TypeScript 型別推斷TypeScript型別
- TypeScript 型別斷言TypeScript型別
- TypeScript void 型別TypeScript型別
- TypeScript 陣列型別TypeScript陣列型別
- TypeScript 函式型別TypeScript函式型別
- TypeScript 數值型別TypeScript型別
- TypeScript 布林型別TypeScript型別
- TypeScript Widened型別TypeScriptIDE型別
- TypeScript 對映型別TypeScript型別