原始類型
:Number,String,Boolean,null,undefined,Symbol 引用類型
:Array,Function,Object TypeScript在ES6的數據類型基礎上,新增瞭如下數據類型:void, any, never, 元組,枚舉,高級類型
web
let cml: number = 1
// es5: let cml = 1
複製代碼
let cml: string = '1'
// es5: let cml = '1'
複製代碼
let cml: boolean = true
// es5: let cml = true
複製代碼
let cml:null = null
// es5: let cml = null
複製代碼
let cml:undefined = undefined
// es5: let cml = undefined
複製代碼
const s2: symbol = Symbol(); // TypeScript
const s1 = Symbol(); // es5
console.log(s1 === s2) // false
複製代碼
void類型能夠被賦值爲undefined和null,可是不能被賦值其餘的,好比stringtypescript
let cml:void = undefined
// es5: let cml = undefined
cml = null
複製代碼
小結:
TypeScript會作靜態類型檢查,當一個變量被定義了某種類型後,再賦值爲其餘類型的值時,則會有報錯提示 數組
可是
markdown
2. 被定義爲null和undefined類型的,只能賦值爲它自己函數
// let cml: Object = {x: 1, y: 1} // 不能直接寫Object,須要具體定義包含的屬性以及對應的類型
let cml: {x: number, y: number} = {x: 1, y: 1}
cml.x = 2
console.log(cml)
複製代碼
1 類型+方括號
ui
let cml: number[] = [1, 2, 3]
// es5: let web = [1, 2, 3]
let web: any[] = [1, '2', true]
複製代碼
2 泛型
this
let cml: Array<number> = [1, 2, 3]
// es5: let cml = [1, 2, 3]
複製代碼
3 接口es5
類數組: 內置對象:IArgumenTypeScript, NodeList, HTMLCollectionspa
function web(name: string, age: number) {
let args: IArgumenTypeScript = argumenTypeScript;
console.log(args); // { '0': 'web', '1': 1 }
}
web('web', 1)
複製代碼
元組是一種特殊的數組,限定了數組的類型和個數翻譯
let cml: [string, number] = ['666', 666]
console.log(cml) // [ '666', 666 ]
複製代碼
使用下標
的方式,能夠只對其中一項賦值,可是對整個對象
賦值時,必須是完整的,且類型不能錯,個數不能多也不能少
let cml: [string, number] = ['666', 666]
cml[0] = '888'
console.log(cml) // ['888', 666]
cml[1] = 888
console.log(cml) // ['888', 888]
cml = ['888', 888]
console.log(cml) // ['888', 888]
cml = ['888', 888, '888'] // 報錯
複製代碼
元組的越界:能夠經過push的方式放入更多的元素,能夠push,可是仍然不能訪問
let cml: [string, number] = ['666', 666]
cml.push('888')
console.log(cml) // ['666', 666, '888']
console.log(cml[2]) // 報錯
複製代碼
any類型能夠任意賦值,不寫至關於any
let cml:any = '123'
cml = 123
複製代碼
never 類型表示的是那些永不存在的值的類型。例如,never 類型是那些老是會拋出異常或根本就不會有返回值的函數表達式。
// 拋出異常的函數
let error: never = () => {
throw new Error('error')
}
// 死循環函數
let endLess: never = () => {
while(true) {}
}
複製代碼
let cml:string | number
cml = '123'
cml = 123
複製代碼
類型斷言
是針對聯合類型,能夠經過斷言爲變量指定一個類型
function cml(a: number | string): void {
console.log(a.length) // 報錯
console.log((<string>a).length) // OK
}
複製代碼
類型別名
除了規定的string/number等類型,TypeScript還支持自定義類型
type Cml = '666' | '888'
function cmlFun(a: Cml): void {
console.log(a)
}
cmlFun('666') // OK
cmlFun(666) // 報錯
複製代碼
enum Gender {Male, Female}
console.log(Gender) // {'0': 'Male', '1': 'Female', 'Male': 0, 'Female', 1}
console.log(Gender['0']) // Male
console.log(Gender['1']) // FeMale
console.log(Gender['Male']) // 0
console.log(Gender['Female']) // 1
複製代碼
對應的ES5的寫法
// typescript
enum Gender {Male, Female}
// ES5
var Gender;
(function (Gender) {
Gender[Gender["Male"] = 0] = "Male";
Gender[Gender["Female"] = 1] = "Female";
})(Gender || (Gender = {}));
複製代碼
enum Direction {
NORTH, // 默認0
SOUTH, // 默認1
EAST, // 默認2
WEST, // 默認3
}
let dir: Direction = Direction.EAST;
console.log('dir', dir) // 2
複製代碼
默認爲0,1,2,3...,若是自定義數字,則後面的枚舉在前一個枚舉值上加1
enum Direction1 {
NORTH = -1,
SOUTH, // 變成0
EAST = 4,
WEST, // 變成5
}
複製代碼
注意,自加的枚舉數值,不保證和已經設定的數值不重合
enum Direction1 {
NORTH = 1,
SOUTH = 0,
EAST,
WEST,
}
console.log(Direction1)
複製代碼
也能夠把數字變成小數
enum Direction1 {
NORTH = 1.5,
SOUTH, // 2.5
EAST, // 3.5
WEST, // 4.5
}
console.log(Direction1)
複製代碼
enum Direction1 {
NORTH = 'a',
SOUTH = 'b',
EAST = 'c',
WEST = 'd',
}
console.log(Direction1) // { NORTH: 'a', SOUTH: 'b', EAST: 'c', WEST: 'd' }
console.log(Direction1['NORTH']) // a
console.log(Direction1['a']) // undefined
複製代碼
常量枚舉是它是使用const
關鍵字修飾的枚舉,普通枚舉有對象,常量枚舉沒有對象,對象實體只存在於TypeScript中,當翻譯爲ES5代碼時,被刪除了。
用途:當咱們不須要這個對象,只須要對象裏的值時,適用常量枚舉,能夠減小編譯時的代碼
// TypeScript 代碼
const enum Gender {Male, Female}
let cml: Gender = Gender['Female']
console.log(cml) // 1
// ES5 代碼
var cml = 1 /* 'Female' */;
console.log(cml);
複製代碼
異構枚舉的成員值是數字和字符串的混合:
enum Cml {
A,
B,
C = "c",
D = "d",
E = 8,
F,
}
複製代碼
數字枚舉和字符串枚舉不一樣的是,數字枚舉相對字符串枚舉多了 「反向映射」:
console.log(Cml[0]) // A
console.log(Cml['A']) // 0
console.log(Cml['C']) // c
console.log(Cml['c']) // undefined
複製代碼
// 定義一個接口
interface IPerson {
name: string,
age: number
}
// 實例化
let p1: IPerson = {
name: 'web',
age: 18
}
複製代碼
一個變量,如上面的p1,若是被聲明爲某一種接口的實例,則變量擁有的屬性必需要和接口定義的同樣,不能多也不能少,不然會報錯。
interface IPerson {
name: string,
age?: number
}
// 實例化
let p1: IPerson = {
name: 'web',
}
複製代碼
interface IPerson {
name: string,
[propName: string]: boolean | string
}
let p1: IPerson = {
name: '123',
married: false, // ok
country: '123' // ok
age: 123 // 報錯
}
複製代碼
若是設定了任意屬性,那麼全部的肯定屬性或者可選屬性必須是任意屬性的子集。
interface IPerson {
readonly name: string,
age: number
}
let p1: IPerson = {
name: '123',
age: 18
}
let p2: IPerson = {
name: '456', // ok
age: 18
}
p1.name = '456' // 報錯
p1.age = 18
複製代碼
readonly,指的是若是不在每次對象賦值狀況下,是不能修改值的。
TypeScript有四種方式去定義函數:
函數的聲明
// ES5裏函數的聲明
function cml(x, y) {
return x + y
}
console.log(cml(1, 2)) // 3
// TypeScript裏函數的聲明
function cml(x: number, y: number): number {
return x + y
}
console.log(cml(1, 2)) // 3
複製代碼
函數的表達式
// ES5函數的表達式
let cml = function(x, y) {
return x + y
}
console.log(cml(1, 2)) // 3
// TypeScript裏函數的表達式
let cml = function(x: number, y: number): number {
return x + y
}
console.log(cml(1, 2)) // 3
複製代碼
函數的別名
type cmlFun = (x: number, y: number) => x + y
let cml: Cml = (a, b) => a + b
console.log(cml(1, 2)) // 3
複製代碼
接口形式定義函數
interface ICml {
(x: number, y: number): number
}
let cml: ICml = function(x: number, y: number) : number {
return x + y
}
console.log(cml(1, 2)) // 3
複製代碼
一個可選參數後面不能再有肯定(必須)參數
function cml(x: number, y?: number): number {
y = y || 0
return x + y
}
console.log(cml(1, 2)) // 3
console.log(cml(1)) // 1
複製代碼
回憶一下ES5裏的argumenTypeScript和ES6裏的args ES5的argumentTypeScript
function cml() {
let sum = 0
for(let item of arguments) {
sum = sum + item
}
return sum
}
console.log(cml(1, 2, 3)) // 6
複製代碼
ES6的args
function cml(...args) {
let sum = 0
for(let item of args) {
sum = sum + item
}
return sum
}
console.log(cml(1, 2, 3)) // 6
複製代碼
TypeScript裏的剩餘參數
function cml(...args: number[]) {
let sum: number = 0
for(let i: number = 0; i < args.length; i ++) {
sum = sum + args[i]
}
return sum
}
console.log(cml(1, 2, 3)) // 6
console.log(cml(1, '2', 3)) // 報錯
複製代碼
C++
裏的函數重載:函數能夠重名,可是參數個數需不一樣,或者參數個數相同可是參數類型不一樣,編譯器經過參數的個數和類型來判斷究竟是調用了哪一個參數。
TypeScript
的函數重載,仍是隻有一個函數,可是能夠對不一樣的參數組合進行靜態類型檢查
function cmlFun(arr: number[]) function cmlFun(arr: string[]) function cmlFun(arr: any[]) { if (typeof(arr[0]) === 'number') { return arr.reduce((pre, cur) => pre + cur) } else if (typeof(arr[0]) === 'string') {
return arr.reduce((pre, cur) => pre + cur)
}
}
console.log(cmlFun([1, 2, 3])) // 6
console.log(cmlFun(['1', '2', '3'])) // 123
複製代碼
ES6裏的類和繼承
// 父類
class Father {
constructor (name, age) {
this.name = name
this.age = age
}
}
// 子類
class Son extends Father{
constructor(phone, ...args) {
super(...args)
this.phone = phone
}
f() {
console.log('this.name', this.name)
}
}
let s = new Son('17807727381', '父類', '36')
s.f() // this.name 父類
複製代碼
static靜態屬性和靜態方法不能經過new的方式調用。
class Father {
static phone = '17723812637'
static f() {
console.log('this.phone', this.phone)
}
constructor (name, age) {
this.name = name
this.age = age
}
}
let fa = new Father('17807727381', '父類', '38')
fa.f() // 報錯
Father.f() // this.phone 17723812637
複製代碼
用於修飾類的屬性以及方法,用public修飾的屬性和方法在類內、外均可以調用。
class Father {
// 須要先定義
public name: string
public age: number
public constructor (name, age) {
this.name = name
this.age = age
}
public f() {
console.log(this.name, this.age)
}
}
let fa = new Father('父類', 36) // 有構造函數,參數不能省略
fa.f() // 父類 36
複製代碼
用於修飾類的屬性以及方法,用protected修飾的屬性和方法,只能由類或者子類的函數訪問。
// 父類
class Father {
protected name: string
public age: number
public constructor (name, age) {
this.name = name
this.age = age
}
f1() {
console.log('this.name', this.name)
}
}
// 子類
class Son extends Father{
public phone: string
constructor(phone, ...args: [string, number]) {
super(...args)
this.phone = phone
}
f2() {
console.log('this.name', this.name)
}
}
let fa = new Father('父類', 36)
fa.f1() // this.name 父類 (父類經過函數訪問: OK)
let s = new Son('17807727381', '父類', 36)
s.f2() // this.name 父類 (子類經過函數訪問: OK)
let fa = new Father('父類', 36)
console.log(fa.name) // 報錯
console.log(fa.age) // 36
複製代碼
用於修飾類的屬性以及方法,用protected修飾的屬性和方法,只能由類函數訪問
// 父類
class Father {
private name: string
public age: number
public constructor (name, age) {
this.name = name
this.age = age
}
f1() {
console.log('this.name', this.name)
}
}
// 子類
class Son extends Father{
public phone: string
constructor(phone, ...args: [string, number]) {
super(...args)
this.phone = phone
}
f2() {
console.log('this.name', this.name) // 報錯
}
}
let fa = new Father('父類', 36)
fa.f1() // this.name 父類 (父類經過函數訪問: OK)
let s = new Son('17807727381', '父類', 36)
s.f2() // 報錯 (子類經過函數訪問: 不OK)
let fa = new Father('父類', 36)
console.log(fa.name) // 報錯
console.log(fa.age) // 36
複製代碼
抽象類:不可實例化,不能直接new出實例來
abstract class Father {
// 須要先定義
public name: string
public age: number
public constructor (name, age) {
this.name = name
this.age = age
}
public f() {
console.log(this.name, this.age)
}
}
let fa = new Father('父類', 36) // 報錯
fa.f()
複製代碼
抽象方法的使用, 若是子類繼承的父類裏有抽象方法,則需在子類裏實現父類的抽象抽象方法
abstract class Father {
// 須要先定義
public name: string
public age: number
public constructor (name, age) {
this.name = name
this.age = age
}
public abstract f1(): void
}
class Son extends Father{
public phone: string
constructor(phone, ...args: [string, number]) {
super(...args)
this.phone = phone
}
public f2(): void {
console.log('this.name', this.name)
}
public f1(): void {
console.log('this.name', this.name)
}
}
let fa: Father = new Son('17836762323', '父類', 36)
fa.f1() // this.name 父類
複製代碼