hackftz

bits change world

导航

深入理解TypeScript——文档篇之类型推断

Posted on 2020-10-13 22:31  hackftz  阅读(514)  评论(0编辑  收藏  举报

一、基础

TypeScript里,在有些没有明确指出类型的地方,类型推论会帮助提供类型

let x = 3; // let x: number

二、最佳通用类型

计算通用类型算法会考虑所有的候选类型,并给出一个兼容所有候选类型的类型。

// demo 1
let x = [0, 1, null, 'haha']; // let x: (string | number | null)[]

// demo 2
class Rhino {
  constructor() {
    
  }
}

class Elephant {
  constructor() {
    
  }
}

class Snake {
  constructor() {
    
  }
}

let zoo = [new Rhino(), new Elephant(), new Snake()]; // let zoo: (Rhino | Elephant | Snake)[]

三、上下文类型

TypeScript类型推论也可能按照相反的方向进行。 这被叫做“按上下文归类”。按上下文归类会发生在表达式的类型与所处的位置相关时。
TypeScript类型检查器使用Window.onmousedown函数的类型来推断右边函数表达式的类型。因此,就能推断出 mouseEvent参数的类型了。
如果函数表达式不是在上下文类型的位置, mouseEvent参数的类型需要指定为any,这样也不会报错了。

window.onmousedown = function(mouseEvent) { // (parameter) mouseEvent: any

    console.log(mouseEvent.button);  //<- Error
};

注:如果上下文类型表达式包含了明确的类型信息,上下文的类型被忽略。

// test 1
window.onmousedown = function(mouseEvent: any) {
    console.log(mouseEvent.button);  //<- Now, no error is given
};

// test 2
interface Name {
  button: string;
}

function App() {
  window.onmousedown = function(mouseEvent: Name) { // TypeScript类型检查器使用Window.onmousedown函数的类型来推断右边函数表达式的类型。 因此,就能推断出 mouseEvent参数的类型了。 
    console.log(mouseEvent.button);  //<- Error
};
// 不能将类型“(mouseEvent: Name) => void”分配给类型“((this: //GlobalEventHandlers, ev: MouseEvent) => any) & ((this: Window, ev: MouseEvent) => any)”。
// 不能将类型“(mouseEvent: Name) => void”分配给类型“(this: GlobalEventHandlers, ev: MouseEvent) => any”。
// 参数“mouseEvent”和“ev” 的类型不兼容。
// 不能将类型“MouseEvent”分配给类型“Name”。
// 属性“button”的类型不兼容。