V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hahaFck
V2EX  ›  程序员

关于 typescript 里面的 never 类型求教!

  •  
  •   hahaFck · 12 天前 · 513 次点击

    never 类型通常表示不会发生的类型,但是下面官方提供的泛型例子有点看不明白 never 的用途了。

    type GetReturnType<Type> = Type extends (...args: never[]) => infer Return
      ? Return
      : never;
    

    这是一个泛型工具类,可以提取函数的返回值类型,但是函数的参数定义成 never 类型数组有些不懂了,看提供的例子,这个定义既能满足无参数函数,也能满足有参数函数。

    type Num = GetReturnType<() => number>;
    //type Num = number
    type Str = GetReturnType<(x: string) => string>;
    //type Str = string
    type Bools = GetReturnType<(a: boolean, b: boolean) => boolean[]>;
    //type Bools = boolean[]
    
    6 条回复    2024-05-01 19:17:31 +08:00
    realJamespond
        1
    realJamespond  
       12 天前
    写成 any[]不也行?
    hahaFck
        2
    hahaFck  
    OP
       12 天前
    @realJamespond 写成 any 我能理解,但是 never 不知道是什么意思,而且按照我的理解是这个函数定义是不支持传参的,但是例子的 type Str = GetReturnType<(x: string) => string>; 这段代码竟然也能通过,奇怪了。
    realJamespond
        3
    realJamespond  
       12 天前
    他这里 args: never[],后面用不上,只是限制参数为数组,不进行推测。如果后面要用到 args 推测应该不能写成 never 的
    Pencillll
        4
    Pencillll  
       12 天前
    这是 TS 里的一个不合理设计

    函数的参数是逆变的,所以 (x: string) => string 可以赋值给 (...args: never[]) => infer Return 的原因是 never[] 可以赋值给 [string],而 never[] 可以赋值给 [string] 的原因是……就是这么设计的

    其实在正常情况下 never[] 是不可以赋值给 [string] 的,但 TS 对于函数里的 ...arg 这种语法做了某些处理导致这种赋值成立

    官方的原话是(第二段): https://github.com/microsoft/TypeScript/issues/48840#issuecomment-1270671527
    SO 有个同样的问题: https://stackoverflow.com/q/78316282
    Pencillll
        5
    Pencillll  
       12 天前
    我根据官方的原话猜测一下 TS 的做法:TS 先假定两个函数的参数数量一致,在这种前提下可以把数组 never[] 当成和元组 [string] 长度一样的元组,也就是 [never],再尝试赋值,而 [never] 是可以赋值给 [string] 的,所以前面的赋值也就成立了
    mark2025
        6
    mark2025  
       9 天前
    @Pencillll 参逆返协。所以有时候 callback 的入参还不能用 unknown 而是得用 any, 否则调用的时候就会报错说 unknown 不能赋值为 string (或者其它正常类型)....
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5519 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 05:59 · PVG 13:59 · LAX 22:59 · JFK 01:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.