TypeScript數(shù)據(jù)類型以及定義方式悔政。
原始數(shù)據(jù)類型
- number 數(shù)值
// 值支持八進制汤徽、十六進制字符編碼涵叮、支持正負無窮、支持NaN
let num:number = 1;
- string 字符串
let str:string = 'b';
// 模板字符串
let result:string = `a${str}c`;
- boolean 布爾
let bool:boolean = true;
- void 空值 (不常用)
// 定義一個沒有返回值的函數(shù)
function unfn():void {
console.log(1);
// return 后面跟除了undefined婆殿、null外的其他任何類型的返回值就會導(dǎo)致發(fā)生編譯錯誤
}
// 定義一個空的變量,它的值只能是undefined或null
let v:void = undefined;
- undefined和null(不常用)
// 定義null和undefined后只能被賦值為null和undefined,但是區(qū)別于void的是诈乒,他們作為其他類型的子類,可以被當做值賦給其他類型婆芦,void類型的則不可以
// 定義一個undefined
let un:undefined = undefined;
// 定義一個null
let nu:null = null;
- any 任意值
let a:any = 1;
a = 'abc';
a = true;
// 通過any則可以定義一個任意值的變量怕磨,這等價于:
let b;
b = 'abc';
b = true
// 未指定類型的變量并且在初始化的時候未賦值喂饥,會被認為是一個任意值
不指定變量類型,不初始化值肠鲫,是任意值员帮,但是不指定變量類型,卻對其進行了初始化导饲,也就是說初始化進行了賦值操作捞高,ts則會進行類型推論:
let a = 1; // 初始化值
a = 'abc';
// 上面的代碼觸發(fā)類型推論就等價于:let a:number = 1;
// 這個時候編譯會發(fā)生錯誤,因為觸發(fā)了ts的類型推論渣锦,它會認為a的類型是number硝岗,賦值string類型就會觸發(fā)錯誤
let b; // 不初始化
b = 1;
b = 'abc';
// 不初始化,b被認為是一個any類型袋毙,因此可以賦值任意類型的值型檀,并不會發(fā)生錯誤
- | 聯(lián)合類型
any任意類型很寬泛,但是讓一個變量的類型只能是任意的兩種以上的類型就難以實現(xiàn)听盖,這里可以通過
聯(lián)合類型
let a:string|number;
a = 'abc';
a = 123;
// 通過|指定聯(lián)合類型胀溺,上面的表示a的類型可以是string也可以是number
a = true;
// a的類型已經(jīng)約束為string或number,當賦值boolean則會發(fā)生編譯錯誤
// 注意:當訪問任意類型的屬性和方法的時候皆看,需要確保他們存在共同的特點仓坞,否則會發(fā)生錯誤,比如訪問a.length,當a為string的時候可以訪問腰吟,當a為number的時候无埃,則會發(fā)生異常,因為number沒有l(wèi)ength屬性
對象數(shù)據(jù)類型
- object
接口interface,它是對行為的抽象蝎困,相當于通過它約定一個集合的類型
// 定義一個接口
interface Person {
name: string,
age: number
}
let tom:Person = {
name: 'tom',
age: 20
}
// 注意:接口一般首字母大寫录语,當接口中定義了固定的key和類型,那么在給對象定義key和賦值的時候禾乘,key和值的類型必須一一對應(yīng),并且key的數(shù)量與接口的數(shù)據(jù)必須一致虽缕,多或者少于接口始藕,都會編譯拋出異常
// 注: null、undefined是所有類型的子類型氮趋,因此賦值這兩個結(jié)果并不會出現(xiàn)意外
上面的這種方式定義一個接口伍派,當規(guī)定key的個數(shù)和值的類型后,我們就無法改變剩胁,但是當有一些key是有可能會用到诉植,有可能就不需要,因此我們需要用到
可選屬性
- 可選屬性表示已經(jīng)定義的屬性可以有也可以沒有昵观,并不代表可以新增未定義的屬性
// 定義接口
interface Person {
name: string,
age?: number
}
let tom:Person = {
name: 'tom',
age: 20
}
let lucy:Person = {
name: 'lucy'
}
// 上面的age加了?號晾腔,因此不會編譯異常
let john:Person = {
name: 'tom',
sex: '男'
}
// 可選的是age舌稀,但是新增加未定義的age則會編譯拋出異常
上面的我們可以定義可選屬性,但是我們依然不能添加新的屬性在里面灼擂,比如說我們不確定將來會有哪些屬性的情況壁查,因此我們需要用到
任意屬性
- 任意屬性表示除了已經(jīng)約定的和可選的屬性,可以任意新增屬性剔应,但是定義任意屬性需要注意的是睡腿,任意屬性的值類型必須是其他屬性值類型的超集,因此峻贮,一般我們都用any席怪,因為其他類型都是any的子集
// 定義接口
interface Person {
name: string,
age?: number,
// 這里的porpName只是相當于任意屬性,僅僅是一個代表任意名稱的占位符纤控,你也可以叫它a||b何恶,它的key類型只能是number或者string,值類型必須是其他key的值類型的超集
// 當[porpName:number]:any的key類型為number的時候嚼黔,那么意味著新增的key的類型必須是number類型才可以
[porpName:string]:any
}
let tom:Person = {
name: 'tom',
age: 20
}
let lucy:Person = {
name: 'lucy'
}
let john:Person = {
name: 'tom',
sex: '男'
}
// 這個時候新增sex將不會編譯報錯
上面的情況已經(jīng)足夠好细层,但是當我們想要給對象中設(shè)置一個固定的值,并且希望它不能被改變唬涧,在js中疫赎,通過const定義常量,對象通過defineProperty或者proxy來完成這一需求碎节,在ts中對象的這個需求實現(xiàn)起來將會更簡單捧搞,可以通過設(shè)置
只讀屬性
// 定義接口
interface Person {
// 設(shè)置readonly屬性
readonly name: string,
age?: number,
[porpName:string]:any
}
let tom:Person = {
name: 'tom',
age: 20
}
let lucy:Person = {
name: 'lucy'
}
let john:Person = {
name: 'tom',
sex: '男'
}
tom.name = 'sare';
// 這個時候編譯則會拋出異常,接口中定義的屬性是只讀狮荔,當對象初始化以后胎撇,這個屬性將不可以再被修改
- 數(shù)組
規(guī)定一個數(shù)組元素的類型,我們通過變量名:類型[]這樣的形式來定義殖氏,定義普通類型晚树,類型后面沒有其他東西,這點需要記住
let arr:number[] = [1, 2, 3, 4, 5];
// 上面種方式定義了數(shù)字元素的類型只能是數(shù)值雅采,除了數(shù)值和他們的子類型null爵憎、undefined,其他類型的值添加到數(shù)組種都會引起編譯異常
arr.push('8');
// 調(diào)用數(shù)組的方法婚瓜,嘗試給數(shù)組添加一個字符串類型的值也會被檢測到從而拋出異常
當然也可通過接口interface來定義數(shù)組宝鼓,不過不常用,它看起來有點麻煩巴刻,但是它是類數(shù)組常用的一種規(guī)定類型的方式
interface NumberArray {
// 這里的index表示數(shù)組中的每一個下標愚铡,也是一個占位,我們用index更加合理胡陪,當然用其他的名稱來表示也是可以沥寥,
//我們都是知道數(shù)組的下標其實就相當于對象的key碍舍,下標默認的只能是數(shù)值類型的,所以我們暫時只能將key的類型設(shè)置為number
[index: number]: number
}
let arr: NumberArray = [1, 2, 3, 4, 5];
// 上面的接口定義數(shù)組中元素的類型為number類型营曼,當你出現(xiàn)除null乒验、number、undefined之外的類型則會發(fā)生異常
類數(shù)組, 我們都知道類數(shù)組不是真實的數(shù)組蒂阱,比如我們一些獲取dom節(jié)點的方法拿到的數(shù)組锻全,又比如arguments,假如我們想限制類數(shù)組的類型录煤,普通的方式就做不到了
function fn() {
let arr:number[] = arguments;
}
// 這里我們通過定義普通數(shù)組的方式定義鳄厌,就會拋出異常,因為arguments是一個類數(shù)組妈踊,我們可以通過接口interface像下面這樣:
function fn() {
let args: {
[index: number]: number;
length: number;
// 這個屬性在嚴格模式下是被廢棄的了嚎,它可以引用在該函數(shù)體內(nèi)執(zhí)行的函數(shù)遞歸調(diào)用
callee: Function;
} = arguments;
}
// 上面通過接口約束數(shù)組元素、length廊营、callee的類型之后歪泳,編譯正常
// 事實上常用的類數(shù)組都有自己的接口定義,如 IArguments, NodeList, HTMLCollection等露筒,因此我們可以這么寫:
function sum() {
// IArguments就等價于上面定義的接口
let args: IArguments = arguments;
}
定義存儲任意類型的數(shù)組
let arr:any[] = [1, 'a', [], {}]
// 使用any定義任意類型