注: symbol 為ES6中新增類型
類型
- string /boolean /number
// 字符串:支持es6 拼接
let sport:string = '足球'
let hobby:string;
hobby = `我愛${sport}` // 支持es6 拼接 ``
console.log( hobby)
// 布爾值
let choice:boolean = false
// 數(shù)值: 和JavaScript一樣馋贤,TypeScript里的所有數(shù)字都是浮點數(shù)。支持二進制畏陕、八進制配乓、十進制、十六進制惠毁、整數(shù)和小數(shù)(整數(shù)可以算進十進制)犹芹、NaN(非數(shù)字)、Infinity(無窮大)
let binNum:number = 0b110 // 二進制
let octNum:number = 0o6 // 八進制
let num:number = 6// 十進制
let hexNum:number = 0x6 // 十六進制
let maxNum:number = Infinity // 無窮大
let isNaNum:number = NaN // 非數(shù)值
注意:
(1)這里的string是小寫的仁讨,和String是有區(qū)別的
(2)使用構(gòu)造函數(shù)(Boolean
羽莺、String
、Number
)創(chuàng)造的對象并不是布爾值洞豁,而是返回一個對象盐固。直接調(diào)用Boolean()
則返回一個布爾值荒给,常用于將一個值強制轉(zhuǎn)換為boolean類型,在此我以構(gòu)造函數(shù) Boolean
為例:
let isBoolean:boolean = new Boolean(1) // 報錯'boolean' is a primitive, but 'Boolean' is a wrapper object. Prefer using 'boolean' when possible.
let isBoolean:boolean = Boolean(1) // true
- array 數(shù)組
- 特點
元素類型限制刁卜,長度不限制
方式1:類型[]
let array: number[] = [1, 2, 3, 4];
數(shù)組的一些方法的參數(shù)也會根據(jù)數(shù)組在定義時約定的類型進行限制:
array.push('2');
// 報錯:Argument of type 'string' is not assignable to parameter of type 'number'
方式2:Array<類型>
(Array Generic) 數(shù)組泛型表示數(shù)組
let array: Array<number> = [1, 2, 3, 4];
自己寫數(shù)組泛型
方式3:接口(不推薦)
數(shù)組的索引就是 number 類型的 0,1,2,3..., JS 中數(shù)組是一類特殊的對象志电,特殊在數(shù)組的鍵(索引)是數(shù)值類型
MyArray 接口模擬原生的數(shù)組接口,并使用 [n: number]來作為索引簽名類型蛔趴。
interface MyArray<T> {
[index:number]: T
}
const testArray: MyArray<string> = ["1", "2", '3']
const testArray2: MyArray<number> = [1, 2, 3]
類數(shù)組:
類數(shù)組不是數(shù)組挑辆,使用數(shù)組的類型會報錯
function add() {
let args: number[] = arguments;
}
// 報錯:Type 'IArguments' is missing the following properties from type 'number[]': pop, push, concat, join, and 26 more.
arguments 為類數(shù)組,應(yīng)該使用下面這種方式定義類型
function sum() {
let args: {
[index: number]: number;
length: number;
callee: Function;
} = arguments;
}
其實常用的類數(shù)組都有自己的接口定義孝情,如 IArguments, NodeList, HTMLCollection 等
function add() {
let args: IArguments = arguments;
}
- tuple 元組
- 語法
let 元組名:[類型1,類型2,類型3] = [值1, 值2,值3]
- 使用
let tup1:[number, string, boolean] = [1, '3', true]
當直接對元組中的變量進行初始化的時候鱼蝉,變量的數(shù)量及變量對應(yīng)的類型必須與類型指定一致 ,否則報錯
let tup1:[number, string, boolean] = [1, '3', true]
let tup2:[number, string, boolean] = [1, '3'] // Property '2' is missing in type '[number, string]' but required in type '[number, string, boolean]'.
let tup3:[number, string] = [1, 3] // Type 'number' is not assignable to type 'string'.
需要注意元祖的越界問題箫荡,雖然可以越界添加元素魁亦,但是不能越界訪問,強烈不建議這么使用羔挡,而且越界的元素的類型會被限制為元組中每個類型的聯(lián)合類型:
let tom: [string, number];
tom = ['Tom', 25];
tom.push('male');
tom.push(true);
// Argument of type 'boolean' is not assignable to parameter of type 'string | number'
let tup4:[string, number] = ['1', 3]
tup3[0] = 'Tom'
tup3.push('apple')
console.log(tup3) // ["Tom", 3, "apple"]
console.log(tup3[2]) // Tuple type '[string, number]' of length '2' has no element at index '2'
- 特點
長度限制洁奈,每個元素的類型限制,但不同元素類型可不同
其實绞灼,可以和數(shù)組進行對比理解:
數(shù)組是合并了相同類型的對象利术,而元組(Tuple)則是合并了不同類型的對象,且類型和數(shù)量已定
- enum 枚舉
- 語法
enum 枚舉名{
枚舉項1 = 值1,
枚舉項2 = 值2 ...
}
注:枚舉項名稱一般由英文和數(shù)字組成低矮,值一般用數(shù)字印叁,默認為0,1,2...
-
使用
默認情況下是從0開始為元素編號
enum gender1 {
male,
female,
unkown
}
console.log(gender1.male) // 0
也可以手動的部分指定成員的數(shù)值或全部,后面的成員一次加1
enum gender2 {
male,
female = 2.5,
unkown
}
console.log(gender2.male) // 0
console.log(gender2.unkown) // 3.5
- 特點
長度限制军掂,每個元素的類型限制喉钢,但不同元素類型可不同
可以理解為:定了元素類型和數(shù)量的數(shù)組,但多個元素類型可不同
-
any 任意類型
一般來說良姆,如果一個變量賦值為某個類型,在賦值過程中是不允許改變類型的幔戏,但是any 類型除外玛追,允許被賦值為任意類型。any類型 一般用在不清楚變量的類型的情況闲延。 在這種情況下痊剖,不想讓類型檢查器對這些值進行檢查。 就可以使用
any
類型來標記這些變量
- 語法
let 變量名: any;
用來表示允許賦值為任意類型垒玲。
- 使用
let anyThing1:any
anyThing1 = 'dd'
anyThing1 = 123
let anyThing2: any[] = [1, true]
anyThing2.push('222')
anyThing2[1] = undefined
console.log(anyThing2) // [1, undefined, "222"]
如果變量在聲明的時候未指定其類型陆馁,那么它會被識別為任意值類型:
let something; // 等同于var something:any;
something = 'seven';
something = 7;
console.log(something); // 7
- void
沒有任何類型,從一定角度可以認為void
類型與any
類型相反合愈。但是在寫代碼的過程中一般不會單獨聲明一個void
類型的變量叮贩,因為其只能賦值undefined
和null
击狮,意義不大
let unusable: void = undefined;
void一般用在當一個函數(shù)沒有返回值時,設(shè)置返回值類型為 void
:
function sayHi(): void {
console.log("Hi,everyone");
}
- null和undefined
undefined
和null
都有自己的類型益老,分別為undefined
和null
彪蓬。但是這并沒有多大意義。
let undefType:undefined = undefined
let nullType:null = null
默認情況下null
和undefined
是所有類型的子類型捺萌。 就是說你可以把 null
和undefined
賦值給其他類型的變量档冬,但是如果設(shè)置了--strictNullChecks
嚴格的空校驗 ,null
和undefined
只能賦值給void
和自身桃纯。 在寫代碼的過程中建議開啟空校驗酷誓。 如果某個變量的類型可能為 number
或null
或undefined
,建議使用聯(lián)合類型number | null | undefined
- never類型
表示永不存在的值的類型态坦,一般用作拋出異逞问或無限循環(huán)的函數(shù)返回類型。
function test():never{
while (true){
...
}
}
function test2():never{
throw new Error('Error');
}
never
類型是ts中的底部類型驮配,是所有類型的子類型娘扩,因此可以賦值給任何類型變量
let cat:string = test()
- 聯(lián)合類型
在實際寫代碼的過程中,有時候定義的變量的類型可能是多種的壮锻,因此聯(lián)合類型便派上用場了琐旁。
- 語法
let 變量名:類型1|類型2... = 值
- 使用
let info:string|null|number;
info = 22
info = '你好嗎'
info = null
let infoArr:(string|number)[];
infoArr = [12, 'sad', 222]
當不確定變量是哪個類型的時候,只能訪問此聯(lián)合類型的所有類型里共有的屬性或方法
let temp:(string|number|boolean);
console.log(temp.length) // Property 'length' does not exist on type 'number'.
9.交叉類型
類似于接口繼承猜绣,用于組合多個類型為一個類型(常用于對象類型)
interface Person { name: string }
interface People { sex: string }
type PersonMan = Person & People
相當于:
type PersonMan = {name: string, sex: string }
當交叉的類型里有相同屬性時
interface Person {
name: string;
title: string | number;
}
interface People {
name: number;
sex: string;
title: string;
}
type PersonMan = Person & People;
let dan: PersonMan = {
name: 'ww', // name 報錯:Type 'string' is not assignable to type 'never'.
sex: 'girl',
title: 'title',
};
name 類型推導(dǎo)結(jié)果是 never灰殴,因為不存在一個值既是 string 又是 number 的。
title 類型推導(dǎo)結(jié)果是 string
總結(jié):
交叉類型算的是 2 個類型的 并集掰邢。就是雙方都有的東西才能合并到一起牺陶,不一樣的將會被排除
如果排除到最后都沒有相同的東西,那么就會變 never 類型(即該類型不存在)
內(nèi)置類型(string,number,boolean,unio 聯(lián)合類型)之間可以使用 &
-
映射類型
參考
映射類型是指基于現(xiàn)有類型產(chǎn)生新的類型
通過遍歷語法拷貝原有類型 在拷貝類型的基礎(chǔ)上進行修改從而產(chǎn)生新的類型
語法:
{[P in K]: T}
Partial 將每個屬性轉(zhuǎn)換為可選屬性
type Partial<T> = {
[P in keyof T]?: T[P];
}
type PersonPartial = Partial<Person>;
Readonly 將每個屬性轉(zhuǎn)換為只讀屬性
type Readonly<T> = {
readonly [P in keyof T]: T[P];
}
type ReadonlyPerson = Readonly<Person>;
Pick 選取一組屬性指定新類型
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
}
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Pick<Todo, "title" | "completed">;
const todo: TodoPreview = {
title: "Clean room",
completed: false,
};
Exclude 去除交集辣之,返回剩余的部分
type Exclude<T, U> = T extends U ? never : T
interface Props {
a?: number;
b?: string;
}
const obj: Props = { a: 5 };
const obj2: Required<Props> = { a: 5 };
Property 'b' is missing in type '{ a: number; }' but required in type 'Required<Props>'
Nullable 轉(zhuǎn)換為舊類型和null的聯(lián)合類型
type Nullable<T> = {
[P in keyof T]: T[P] | null
}
type NullablePerson = Nullable<Person>;
Omit 適用于鍵值對對象的Exclude掰伸,去除類型中包含的鍵值對
type Omit = Pick<T, Exclude<keyof T, K>>
interface Todo {
title: string;
description: string;
completed: boolean;
}
type TodoPreview = Omit<Todo, "description">;
const todo: TodoPreview = {
title: "Clean room",
completed: false,
};
Required 將每個屬性轉(zhuǎn)換為必選屬性
type Required<T> = {
[P in keyof T]-?: T[P]
}
interface Props {
a?: number;
b?: string;
}
const obj: Props = { a: 5 };
const obj2: Required<Props> = { a: 5 };
- 接口
interface Person {
name: string;
age: number;
}
let tom: Person = {
name: 'Tom',
age: 25
};
接口一般首字母大寫。
注意:定義的變量比接口多或者少了一些屬性是不允許的:
可選屬性
interface Person {
name: string;
age?: number;
}
let tom: Person = {
name: 'Tom',
age: 25
};
建議:
書寫的時候可選屬性建議放在最后
任意屬性
interface Person {
name: string;
age?: number;
[key: string]: any;
}
let tom: Person = {
name: 'Tom',
gender: 'male'
};
注意:
一旦定義了任意屬性怀估,那么確定屬性和可選屬性的類型都必須是它的類型的子集
interface Person {
name: string;
age?: number;
[key: string]: string;
}
let tom: Person = {
name: 'Tom',
age: 25,
gender: 'male'
};
// 報錯:Property 'age' of type 'number' is not assignable to 'string' index type 'string'.
一個接口中只能定義一個任意屬性狮鸭。如果接口中有多個類型的屬性,則可以在任意屬性中使用聯(lián)合類型:
interface Person {
name: string;
age?: number;
[key: string]: string | number;
}
建議:
實際開發(fā)中不要使用過多的任意類型多搀,使用到什么屬性就把對應(yīng)的類型添加到接口里即可歧蕉。
只讀屬性
如果只希望對象中的一些字段只能在創(chuàng)建的時候被賦值,那么可以用 readonly 定義只讀屬性:
// interface Person {
readonly id: number;
name: string;
age?: number;
[propName: string]: any;
}
let tom: Person = {
id: 89757,
name: 'Tom',
gender: 'male'
};
tom.id = 9527;
// 報錯:Cannot assign to 'id' because it is a read-only property.
-
字符串字面量
字符串字面量類型用來約束取值只能是某幾個字符串中的一個康铭。
type EventNames = 'click' | 'scroll' | 'mousemove';