【TypeScript】001-類型、接口、函數、類

原始類型:Number,String,Boolean,null,undefined,Symbol 引用類型:Array,Function,Object TypeScript在ES6的數據類型基礎上,新增瞭如下數據類型:void, any, never, 元組,枚舉,高級類型web

1、類型

1.1 Number類型

let cml: number = 1
// es5: let cml = 1
複製代碼

1.2 String類型

let cml: string = '1'
// es5: let cml = '1'
複製代碼

1.3 Boolean類型

let cml: boolean = true
// es5: let cml = true
複製代碼

1.4 Null類型

let cml:null = null
// es5: let cml = null
複製代碼

1.5 Undefined類型

let cml:undefined = undefined
// es5: let cml = undefined
複製代碼

1.6 Symbol類型

const s2: symbol = Symbol(); // TypeScript
const s1 = Symbol();  // es5
console.log(s1 === s2) // false
複製代碼

1.7 Void類型

void類型能夠被賦值爲undefined和null,可是不能被賦值其餘的,好比stringtypescript

let cml:void = undefined
// es5: let cml = undefined
cml = null
複製代碼

小結:TypeScript會作靜態類型檢查,當一個變量被定義了某種類型後,再賦值爲其餘類型的值時,則會有報錯提示 image.png數組

可是markdown

  1. 當被從新賦值爲null和undefined時,則不會報錯,由於null和undefined能夠當作是全部類型的子集

image.png 2. 被定義爲null和undefined類型的,只能賦值爲它自己函數

1.8 對象

// 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.9 數組

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)
複製代碼

1.10 元組

元組是一種特殊的數組,限定了數組的類型和個數翻譯

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]) // 報錯
複製代碼

1.11 any類型

any類型能夠任意賦值,不寫至關於any

let cml:any = '123'
cml = 123
複製代碼

1.12 never類型

never 類型表示的是那些永不存在的值的類型。例如,never 類型是那些老是會拋出異常或根本就不會有返回值的函數表達式。

// 拋出異常的函數
let error: never = () => {
  throw new Error('error')
}

// 死循環函數
let endLess: never = () => {
  while(true) {}
}
複製代碼

1.13 聯合類型

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) // 報錯
複製代碼

1.14 enum枚舉類型

1. 基本用法

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 = {}));
複製代碼

2. 數字的枚舉

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)
複製代碼

image.png

也能夠把數字變成小數

enum Direction1 {
  NORTH = 1.5,
  SOUTH, // 2.5
  EAST, // 3.5
  WEST, // 4.5
}
console.log(Direction1)
複製代碼

3. 字符串的枚舉

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
複製代碼

4. 常量枚舉

常量枚舉是它是使用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);
複製代碼

5. 異構枚舉

異構枚舉的成員值是數字和字符串的混合:

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
複製代碼

2、接口

1. 肯定屬性

// 定義一個接口
interface IPerson {
  name: string,
  age: number
}

// 實例化
let p1: IPerson = {
  name: 'web',
  age: 18
}
複製代碼

一個變量,如上面的p1,若是被聲明爲某一種接口的實例,則變量擁有的屬性必需要和接口定義的同樣,不能多也不能少,不然會報錯。

2. 可選屬性

interface IPerson {
  name: string,
  age?: number
}

// 實例化
let p1: IPerson = {
  name: 'web',
}
複製代碼

3. 任意屬性

interface IPerson {
  name: string,
  [propName: string]: boolean | string
}

let p1: IPerson = {
  name: '123',
  married: false, // ok
  country: '123' // ok
  age: 123 // 報錯
}
複製代碼

若是設定了任意屬性,那麼全部的肯定屬性或者可選屬性必須是任意屬性的子集。

4. 只讀屬性

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,指的是若是不在每次對象賦值狀況下,是不能修改值的。

3、函數

1. 函數定義

TypeScript有四種方式去定義函數:

  1. 函數的聲明
  2. 函數的表達式
  3. 函數的別名
  4. 接口定義函數

函數的聲明

// 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
複製代碼

2.可選參數

一個可選參數後面不能再有肯定(必須)參數

function cml(x: number, y?: number): number {
  y = y || 0
  return x + y
}
console.log(cml(1, 2))  // 3
console.log(cml(1))  // 1
複製代碼

3.剩餘參數

回憶一下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)) // 報錯
複製代碼

4. 函數重載

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
複製代碼

4、類

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 父類
複製代碼

1. static關鍵字(ES6+)

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
複製代碼

2. public關鍵字

用於修飾類的屬性以及方法,用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
複製代碼

3. protected關鍵字

用於修飾類的屬性以及方法,用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
複製代碼

4. private關鍵字

用於修飾類的屬性以及方法,用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
複製代碼

5. abstract關鍵字

抽象類:不可實例化,不能直接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 父類

複製代碼
相關文章
相關標籤/搜索