typeScript學習

typescript

元組

let arr: [string,number] = ['haha',3]

enmu類型

enum Color {
  Red = 3,
  Blue,
  Green
}
let color = Color[0]
console.log(color) // undefined

let color2 = Color[3]
console.log(color2) //red

能夠指定序號typescript

enum Color {
  Red = 3,
  Blue = 5,
  Green = 7
}

any類型

void類型

沒有返回值數組

function test ():void {
    console.log("void")
}

undefinednull

undefinednull 的子類型,因此能夠賦值給它ide

let u: null = null
let n: null= undefined

never類型

它是任何類型的子類型,=函數

Object 類型

類型推斷和類型斷言

let someValue: any = "hello world" // 此處就是類型斷言
// let length: number = (<string>someValue).length // 強制轉化

let someLength: number = (someValue as string).length //類型推斷
console.log(someLength)

變量聲明

解構

  • 剩餘參數ui

  • 對象this

    let o = {
      a: 'haha',
      b: 22
    }
    
    let {a: newName1, b:newName2} = o
    // ==>
    let newName1 = o.a 
    let newName2 = o.b
    //ts 
    let {a,b}: {a: string, b:number}  = o
    function f({a,b = '3'} = {a = ''}):void {}
    f()
    f({}) 能夠不傳第一個數組,可是若是傳了必須就有值
  • 數組rest

展開

  • 數組code

    let arr = [3,4,5]
    let arr2 = [7,8,9]
    let arr3 = [...arr,...arr2]
    console.log(arr3)
  • 對象對象

    let obj = {
      name: 'kangkang',
      age: 32
    }
    
    let obj2 = {...obj,class: 'four'}
    console.log(obj2)

    同名屬性後面的值會覆蓋前面的值!!!繼承

接口

//定義接口使用interface 須要定義接口的名字,接口不在乎屬性的順序,只在乎屬性名和值得類型
interface LabelValue {
  label: string
}

function printLabel (labelObject: LabelValue) {
  console.log(labelObject.label)
}

let obj = {name: 'kangkang', label: 'string'}

printLabel(obj) // 傳進去的對象包含被檢測屬性

可選屬性and只讀屬性

可選屬性必須在必須屬性後面,且可選屬性時可選的

interface value {
    x?: number,
    y?: string
}

一些屬性只在定義時須要改變能夠選用只讀屬性

interface value {
    readonly x: number,
    readonly y: string
}

額外的屬性檢查和函數類型和可索引的類型

typeScript會對對象自變量作額外的變量檢查,如何避開?

interface values {
  x?: string,
  y?: number
}

// let testValues: values = {xx: 'haah',x: 'haha',y: 333}

let a = { xx: 'haah', x: 'haha', y: 333 }
let testValues: values = a

或者

interface values {
  x?: string
  y?: number
  [popsName: string]: any
}

let a = { xx: 'haah', x: 'haha', y: 333 }

類類型和繼承接口+ 混合類型+ 接口繼承類型

class Clock implements Clock {
  constructore(x: number, y: number) {

  }
  currentTime:Date
  newTime(d: time) {
    this.currentTime = d
  }
}

何時該用靜態接口何時該用動態接口?

靜態類類型

interface ClockConstructor {
  new (x: number, y: numebr): Clock
}

構造器裏的類型須要經過靜態類型來對其進行檢查,如上.

繼承接口(單繼承和多繼承)
interface Father { 
  color: string
}
interface Mother {
  phone: number
}
interface Son extends Father,Mother{
  age: string
}
let person = {} as Son
person.color = 'red'
person.age = '12'
person.phone = 32

console.log(person)

混合類型

interface Counter {
  (x:number): number
  interel: string
  reset() :void
}

function getValue(): Counter {
  let counter = (function(x: number ) {
    return x
  }) as Counter

  counter.interel = '32'
  counter.reset = function() {console.log('haha')}

  return counter
}

getValue().reset()
接口繼承類

當一個接口繼承一個類的類型時,會繼承它的一些私有成員什麼的,因此當接口繼承類後,建立新類使用接口後若是新類沒有繼承原類直接指定此接口會致使一些私有屬性等沒有成功被繼承,從而報錯

class orset  {
  private state: any
}

interface orsets extends orset {
  reset(): void
}

class test extends orset impelments orset{
  reset(): void{
    console.log("rest implement")
  }
}
// 未繼承orset類,缺乏私有屬性state
// class  test2  implements orset {
//   reset() {
//     console.log("error")
//   }
// }

類 繼承

class person {
  name: string
  constructor(name: string) {this.name = name}
  sayName(a:string):void {
    console.log(this.name  + a)
  }
}

class mary extends person {
  constructor(name: string) {
    console.log("構造函數執行...")
    // 調用父類構造函數
    super(name);
  }
  sayName(a: string = "你好"): void {
    console.log("mary ...");
    // 調用父類方法
    super.sayName(a);
  }
}

let test = new mary('mary')
test.sayName()

類公有、私有、受保護的修飾符 + readonly 修飾符

publicprivateprotected

私有成員實例及子類實例子類也不可訪問,可是保護成員的子類型能夠訪問父類

類的靜態屬性和存取器

let seret = 'acdsdfadfa'
class test {
  private name: string
  // constructor (name: string) {
  //   this.name = name
  // }
  get names() {
    return this.name
  }
  set names(newName: string) {
    if(seret && seret === 'acdsdfdfa') {
      this.name = newName
    }else {
      console.log("它是穿山甲")
    }
  }
}
let newTest = new test()
newTest.names = 'hah'
// 我是穿山甲

靜態屬性時存在類的自己(可直接經過類來訪問它),不是在類的實例上

class instance {
  static origin = { x: 0, y: 0 };
  scale: number;
  constrouctor(scale: number) {
    this.scale = scale;
  }

  calculateRadius(point: { x: number; y: number }) {
    // 直接經過類名去使用它
    let xDist = point.x - instance.origin.x;
    let yDist = point.y - instance.origin.y
    return { xDist, yDist };
  }
}

抽象類

抽象類裏面包含抽象方法,抽象方法不能被直接實現須要去派生類中實現

抽象類也不能被實例化

類也能夠做爲類型

abstract class city {
  city: string
  constructor (city:string) {
    this.city = city
  }
  // 抽象類的方法也須要在派生類中去實現
  abstract sayCity() :void
}
// let x = new city() // 沒法建立抽象類的實例
class citys extends city {
  static adr: string = 'kangkang'
  constructor() {
    super('nanjing')
  }
  sayCity():void {
    console.log(this.city)
  }

  sayHello(value:string):void {
    console.log(value)
  }
}

// 此處的citys是實例類型
let x:citys = new citys()
x.sayCity()
x.sayHello('haha')

//  typeof citys是得到citys類 類型
let y: typeof citys = citys
y.adr = 'hehe'

 let z: citys = new y()
 z.sayHello('hwhw')

函數

匿名函數和命名函數

函數類型包含兩部分,一部分是參數類型一部分是函數返回類型

let pro:(name: string,age: number) => number = function(x: string,y:number):number { return age++}

可選參數和默認參數

function buildName(firstName: string, lastName? : string ) {
  if(lastName) {
    return firstName + lastName
  }else {
    return firstName
  }
}

let x = buildName('dai')
console.log(x)

可選參數必須在必須參數的後面,而帶有默認參數的可選參數能夠在前面

剩餘參數

function buildName(firstName:string, ...rest: string[]){}

this問題

泛型

爲何須要泛型?泛型如何使用?

好比當你在函數中須要輸入和返回的類型統一可是你在未使用前還不肯定會是哪一種類型的時候

// 此時傳入的類型和返回的就不必定會相同了*

function test (x:any) :any {

  return x + ''

}

使用方法

let x1 = test<string>('string')

let x2 = test('string')

當使用了T類型不存在的屬性後會報錯,咱們使用具備此屬性好比數組能夠

function list <T> (type: T) {
  return type.length //類型T上不存在屬性length
}
function list2<T>(type: T[]) {
  return type.length
}

泛型類型

function list2<T>(type: T) {
  return type
}
interface iden <T> {
  (arg:T): T
}
let s: iden<number> = list2

泛型類

將泛型的類型名放在類名的後面可讓裏面都可以使用這個類型的變量來定義

class iden<T> {
  name: string
  key: T
  add: (s:T) => T
}

let x = new iden<number>()

x.add = function (s: number) { 
  return s + 2
}

泛型不能夠做用於靜態屬性的

泛型約束

interface types {
  length: number
}

let s = function<T extends types>(s: T) {
  console.log(s.length)
}

s("33")
s(22) // error 22不具備length屬性
s({length: 222})

類型約束(k必須是T的屬性才行)

function x<T, K extends keyof T>(obj: T, key: K) {
  return obj[key]
}
let obj = {a: 3, b: 4, c: 5}
let s = x(obj,'b') 
let s2 = x(obj,'s') // error 類型s的參數不能賦值給類型 a| b| c的參數
class one {
  name: string
}

class two {
  age: number
}

class profile {
  key: number
}

class a extends profile {
  sayName: one
}

class b extends profile {
  sayAge : two
}

function createFn <T extends profile>(c: new() => T): T {
  return new c()
}
let test = createFn(b).sayAge.age
let test2 = createFn(a).sayName.name

類型推斷和最佳通用類型和上下文類型

在聲明變量和參數類型以及返回類型的時候會出現類型推斷

考慮以下狀況

let x = [0,'a',null] // number | string | null

其中任意類型都可


以下狀況

class Mother {}
class Son extends mother{
  name: string 
}
class Daughter  extends mother{
  name: string
}

let s = [new son(), new daughter()]

當咱們s被推斷出mother時上面這種寫法並不能實現

let s: Mother = [new son(), new daughter()]

上下文類型

window.onmousedown = function(event) {
  console.log(event.click)
}
// mouseEvent 上不存在click事件

window.onmousedown = function(event: any) {
  console.log(event.click);
};

第一個會經過左邊來推斷右邊的類型,對於mousedown來講它不存在click事件,而你指定類型就會使得這樣的類型推斷失效

class Mother {}
class Son extends mother {
  name: string;
}
class Daughter extends mother {
  name: string;
}
// Mother會做爲最佳通用類型
function x(): Mother[] {
  return [new Son(), new Daughter()]
}

高級類型

  • 交叉類型

    會將多個類型合併爲一個類型

  • 聯合類型

    調用方法須要去調用它們的公有方法

  • 類型保護

    類型判斷?

相關文章
相關標籤/搜索