TypeScript 是一種類型化的語言,容許你指定變量、函數參數、返回的值和對象屬性的類型。前端
如下是 TypeScript 高級類型的使用方法總結,並且帶有例子。程序員
Intersection 類型是一種把對多種類型進行組合的方法。這意味着你能夠把給定的多種類型合併,並獲得一個帶有所有屬性的新類型。面試
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
,並使用 &
符號來構造交 intersection 類型。typescript
Union 類型用來在給定變量中使用不一樣類型的註釋。segmentfault
type UnionType = string | number function showType(arg: UnionType) { console.log(arg) } showType("test") // Output: test showType(7) // Output: 7
showType
函數是一個 union 類型,它可以接受字符串和數字做爲參數。服務器
泛型類型是一種用來重用給定類型的一部分的方式。它用來處理參數傳入的類型 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
。因爲它是可重用的,所以咱們能夠用字符串和數字來調用它。ide
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
,而後將它們用做屬性的類型註釋。也就是說,咱們如今能夠給這個該接口並提供兩個不一樣的類型做爲參數。
TypeScript 提供了方便的內置實用工具,可幫助咱們輕鬆地操做類型。在使用時須要將要處理的類型傳遞給 <>
。
Partial<T>
Partial 容許你將全部類型爲 T
的屬性設爲可選。它將在每一個字段旁邊添加一個 ?
標記。
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
類型做爲參數。如今全部字段都變成了可選的。
Required<T>
與 Partial
不一樣,Required
使全部類型爲 T
的屬性成爲必需的。
interface RequiredType { 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 將會引起錯誤。
Readonly<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: 沒法給'id'從新賦值,由於它是隻讀屬性。
在代碼中用 Readonly
來使 ReadonlyType
的屬性不可被從新賦值。若是你必定要爲這些字段賦值的話,將會引起錯誤。
Besides that, you can also use the keyword readonly
in front of a property to make it not reassignable.
除此以外,還能夠在屬性前面使用關鍵字「 readonly」,以使其沒法從新分配。
interface ReadonlyType { readonly id: number name: string }
Pick<T, K>
它容許你經過選擇某個類型的屬性 k
,從現有的模型 T
中建立一個新類型。
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
是要選擇的屬性。還能夠通用管道符號 (|
)將它們分開來選擇多個字段。
Omit<T, K>
Omit
與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">'
Omit
的工做方式與 Pick
相似。
Extract<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
提取出來。若是你有多個共享字段,Extract
將會提取全部類似的屬性。
與 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
能夠按預期返回這些字段。
Record<K,T>
Record
能夠幫你構造一個類型,該類型具備給定類型 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
的工做方式相對簡單。在代碼中,它指望用 number
做爲類型,這就是咱們把 0、1 和 2 做爲 employees
變量的鍵的緣由。若是試圖將字符串用做屬性,則會引起錯誤。接下來,屬性集由 EmployeeType
給出,所以該對象具備字段 id
、 fullName
和 role
。
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
,NonNullable
經過從該類型中排除 null
和 undefined
來構造新類型。也就是說,若是你傳遞可空的值,TypeScript 將會引起錯誤。
順便說一句,若是把 --strictNullChecks
標誌添加到 tsconfig
文件,TypeScript 將應用非空性規則。
映射類型容許你獲取現有模型並將其每一個屬性轉換爲新類型。注意,前面介紹的一些實用工具類型也是映射類型。
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 將會報錯。
類型保護使你能夠用運算符檢查變量或對象的類型。它其實是一個檢查用 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
。
用來對兩種類型進行測試,並根據測試的結果選擇其中的一種。
type NonNullable<T> = T extends null | undefined ? never : T
這個例子中的 NonNullable
檢查該類型是否爲 null 並根據該類型進行處理。