代码之家  ›  专栏  ›  技术社区  ›  Raine Revere wjohnsto

当函数返回any时,如何导致类型错误?

  •  0
  • Raine Revere wjohnsto  · 技术社区  · 2 年前

    当特定函数返回时,如何使TypeScript引发错误 any ?

    我可以将鼠标悬停在编辑器中的函数名上查看返回类型,但最好是得到一个错误或警告。我经常使用各种泛型和索引类型来处理复杂的函数。我想我终于把类型弄对了,但实际上有一个错误 任何 这是在我的类型表达式没有正确缩小时推断出来的。

    理想情况下,这将采取一个简单语句的形式,我可以将其留在代码中,以确保没有回归。

    function getNumber (): number { return 0; }
    function getAny (): any { return 0; }
    
    // Is there a simple, assert-like statement that will 
    // succeed on getNumber and fail on getAny?
    

    注意:我不是在寻找编译器选项。为了简单起见,我明确地将any设置为 getAny ,但现实世界中的函数可以很好地以一种不太明显的方式推断任何函数。此外,我可能无法添加 noImplicitAny 而不会在项目中引起一连串的其他错误。需要一个在 任何 残余

    3 回复  |  直到 2 年前
        1
  •  1
  •   jcalz    2 年前

    这与 Disallow call with any 但足够明显,我不想把它当作复制品来结束。就像在这个问题的答案中一样,你可以建立一个 any -检测器”,利用其故意不健全的事实 intersections 具有 任何 也产生 任何 (参见 Type intersections using any )。我们可以写作

    type NotAny<T> = 0 extends (1 & T) ? never : unknown;
    

    因此 NotAny<any> never 但是 NonAny<X> 对于任何其他类型 X unknown 。(如果您有- 任何 类型 十、 ,类型 1 & X 将是非- 任何 的亚型 1 0 不延伸 1. 但是 1 & any 只是 任何 0 extends any )

    然后你可以用这个探测器 constraint 关于断言函数:

    declare function doesNotReturnAny<T extends NotAny<T>>(fn: (...args: any) => T): void;
    
    doesNotReturnAny(getNumber); // okay
    doesNotReturnAny(getAny); // error
    

    这是因为,如前所述 任何 可分配给 从不 所以 getNumber 原因 T 推断为 number 数字 可分配给 未知的 但是 getAny 原因 T 推断为 任何 任何 不可分配给 从不

    Playground link to code

        2
  •  0
  •   Raine Revere wjohnsto    2 年前

    我找到了一个解决方案,但我对简洁的替代方案非常感兴趣。

    如果您尝试分配,Typescript将抛出错误 any never 变量因此,您可以通过获取返回类型和一个没有重叠的唯一符号类型的交集来设置一个失败的断言。重要的是,这将始终评估 从不 ,除非返回类型为 任何

    const NEVER_SYMBOL = Symbol('NeverSymbol')
    type NeverSymbol = typeof NEVER_SYMBOL
    
    function getNumber () { return 0; }
    function getAny (): any {}
    
    // passes because NeverSymbol & number === never
    const a: never = NEVER_SYMBOL as NeverSymbol & ReturnType<typeof getNumber>
    
    // fails because NeverSymbol & any === any (intended)
    // Is there an easier way?
    const b: never = NEVER_SYMBOL as NeverSymbol & ReturnType<typeof getAny>
    
    

    View in TS playground

    推荐文章