TypeScript(二) 常見數(shù)據(jù)類型

image-20200528172415100

注: symbol 為ES6中新增類型

類型

  1. 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 羽莺、StringNumber)創(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
  1. 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;
}
  1. 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ù)量已定

  1. 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ù)組,但多個元素類型可不同
  1. 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
  1. void

沒有任何類型,從一定角度可以認為void類型與any類型相反合愈。但是在寫代碼的過程中一般不會單獨聲明一個void類型的變量叮贩,因為其只能賦值undefinednull击狮,意義不大

let unusable: void = undefined;

void一般用在當一個函數(shù)沒有返回值時,設(shè)置返回值類型為 void

function sayHi(): void {
    console.log("Hi,everyone");
}
  1. null和undefined

undefinednull 都有自己的類型益老,分別為undefinednull 彪蓬。但是這并沒有多大意義。

let undefType:undefined = undefined
let nullType:null = null

默認情況下nullundefined是所有類型的子類型捺萌。 就是說你可以把 nullundefined賦值給其他類型的變量档冬,但是如果設(shè)置了--strictNullChecks 嚴格的空校驗 ,nullundefined只能賦值給void和自身桃纯。 在寫代碼的過程中建議開啟空校驗酷誓。 如果某個變量的類型可能為 numbernullundefined,建議使用聯(lián)合類型number | null | undefined

  1. never類型

表示永不存在的值的類型态坦,一般用作拋出異逞问或無限循環(huán)的函數(shù)返回類型。

function test():never{
    while (true){
        ...
    }
}
function test2():never{
    throw new Error('Error');
}

never 類型是ts中的底部類型驮配,是所有類型的子類型娘扩,因此可以賦值給任何類型變量

let cat:string = test()
  1. 聯(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)合類型)之間可以使用 &

  1. 映射類型
    參考
    映射類型是指基于現(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 };
  1. 接口
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.
  1. 字符串字面量
    字符串字面量類型用來約束取值只能是某幾個字符串中的一個康铭。
type EventNames = 'click' | 'scroll' | 'mousemove';
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末惯退,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子从藤,更是在濱河造成了極大的恐慌催跪,老刑警劉巖锁蠕,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異叠荠,居然都是意外死亡匿沛,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門榛鼎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逃呼,“玉大人,你說我怎么就攤上這事者娱÷樟” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵黄鳍,是天一觀的道長推姻。 經(jīng)常有香客問我,道長框沟,這世上最難降的妖魔是什么藏古? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮忍燥,結(jié)果婚禮上拧晕,老公的妹妹穿的比我還像新娘。我一直安慰自己梅垄,他們只是感情好厂捞,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著队丝,像睡著了一般靡馁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上机久,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天臭墨,我揣著相機與錄音,去河邊找鬼膘盖。 笑死裙犹,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的衔憨。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼袄膏,長吁一口氣:“原來是場噩夢啊……” “哼践图!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起沉馆,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤码党,失蹤者是張志新(化名)和其女友劉穎德崭,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體揖盘,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡眉厨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了兽狭。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片憾股。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖箕慧,靈堂內(nèi)的尸體忽然破棺而出服球,到底是詐尸還是另有隱情,我是刑警寧澤颠焦,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布斩熊,位于F島的核電站,受9級特大地震影響伐庭,放射性物質(zhì)發(fā)生泄漏粉渠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一圾另、第九天 我趴在偏房一處隱蔽的房頂上張望霸株。 院中可真熱鬧,春花似錦盯捌、人聲如沸淳衙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽箫攀。三九已至,卻和暖如春幼衰,著一層夾襖步出監(jiān)牢的瞬間靴跛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工渡嚣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留梢睛,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓识椰,卻偏偏與公主長得像绝葡,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子腹鹉,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容