TypeScript 3.4

    因此, 在 noImplicitAny 下访问 this 上的未知值,你可能收到错误提示。

    请注意,在 noImplicitThis 下编译的代码不会在此处遇到任何更改。

    在某些情况下,TypeScript 3.4 的推断改进可能会产生泛型的函数,而不是那些接收并返回其约束的函数(通常是 {})。

    1. declare function compose<T, U, V>(f: (arg: T) => U, g: (arg: U) => V): (arg: T) => V;
    2. function list<T>(x: T) { return [x]; }
    3. function box<T>(value: T) { return { value }; }
    4. let f = compose(list, box);
    5. let x = f(100)
    6. // 在 TypeScript 3.4 中, 'x.value' 的类型为
    7. // number[]
    8. // 但是在之前的版本中类型为
    9. //
    10. // {}[]
    11. //
    12. // 因此,插入一个 `string` 类型是错误的
    13. x.value.push("hello");

    TypeScript 现在使用函数调用时传入的类型(如下例中的 then)作为函数上下文参数类型(如下例中的箭头函数)。

    这通常是一种改进,但在上面的例子中,它导致 truefalse 获取不合需要的字面量类型。

    1. Argument of type '(x: number) => Promise<{ success: false; }> | { success: true; }' is not assignable to parameter of type '(value: number) => { success: false; } | PromiseLike<{ success: false; }>'.
    2. Type 'Promise<{ success: false; }> | { success: true; }' is not assignable to type '{ success: false; } | PromiseLike<{ success: false; }>'.
    3. Type '{ success: true; }' is not assignable to type '{ success: false; } | PromiseLike<{ success: false; }>'.
    4. Type '{ success: true; }' is not assignable to type '{ success: false; }'.
    5. Types of property 'success' are incompatible.

    合适的解决方法是将类型参数添加到适当的调用——本例中的 then 方法调用。

    strictFunctionTypes 之外一致性推断优先

    但是,对于带有 keyof 状态的类型参数的泛型 类型——逆变用法——这些类型表现不正确。

    在 TypeScript 3.4 中,现在可以在所有情况下正确探测使用 interface 声明的类型的变动。

    这导致一个可见的重大变更,只要有类型参数的接口使用了 keyof(包括诸如 Record<K, T> 之类的地方,这是涉及 keyof K 的类型别名)。下例就是这样一个可能的变更。

    1. interface HasX { x: any }
    2. declare const source: HasX | HasY;
    3. declare const properties: KeyContainer<HasX>;
    4. interface KeyContainer<T> {
    5. key: keyof T;
    6. }
    7. function readKey<T>(source: T, prop: KeyContainer<T>) {
    8. console.log(source[prop.key])
    9. }
    10. // 这个调用应该被拒绝,因为我们可能会这样做
    11. // 错误地从 'HasY' 中读取 'x'。它现在恰当的提示错误。