//类型推论
let x = [0,1,null];
/*为了推断x的类型,我们必须考虑所有元素的类型。计算通用类型算法会考虑所有的候选类型,并给出一个兼容所有
候选类型的类型*/

//有些时候候选类型共享相同的通用类型,但是却没有一个类型能作为所有候选类型的类型。
//如
// let zoo = [new Rhino(),new Elephant(),new Snake()];
/*此处我们想让zoo被推断为Animal[]类型,但是这个数组里没有对象是Animal类型的,因此不能被
推断出这个结果,*/

//此处不能用的时候我们需要明确的指出类型
// let zoo:Animal[] = [new Rhino(),new Elephant(),new Snake()];
//如果没有招到最佳通用类型的话,类型推断的结果为联合数组类型(Rhino | Elephant | Snake)[]

//上下文类型
/*上下文归类会发生在表达式的类型与所处的位置相关时*/
//例
window.onmousedown = function (mouseEvent) {
    console.log(mouseEvent.button);//<-error
}
//这个例子会出现类型错误,使用window.onmousedown函数的类型来推断右边函数表达式的类型。
/*因此,就能推断出 mouseEvent参数的类型了。 如果函数表达式不是在上下文类型的位置,
mouseEvent参数的类型需要指定为any,这样也不会报错了。*/
window.onmousedown = function(mouseEvent: any) {
    console.log(mouseEvent.button);  //<- Now, no error is given
};

function createZoo(): Animal[] {
    return [new Rhino(), new Elephant(), new Snake()];
}
//此处Animal会作为上下文类型最佳通用类型的候选。