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

请教关于 TypeScript 类型索引 & 推断的一个问题

  •  
  •   vsomeone · 2020-10-28 19:35:40 +08:00 · 2145 次点击
    这是一个创建于 1464 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前我需要写一个类型,现在写的定义是:

    interface IState {
        something: number;
        another: string;
    }
    
    type HandlerFactory = (key: keyof IState) => (value: IState[key]) => void;
    

    也就是说,HandlerFactory 指的是一类函数,其唯一参数是 IState 对象的一个 key,返回一个新的函数,此函数的唯一参数类型应当对应 IState[key] 的类型(例如,handlerFactory('something') 生成一个函数,此函数的签名为 (value: number) => void )。

    目前这样写,TypeScript 会报错 key 是一个值,此处把它作为类型来使用('key' refers to a value, but is being used as a type here. Did you mean 'typeof key'?ts(2749))。我不太理解的是,为什么我已经限定了 key 的范围( keyof IState ),TS 仍然会有这样的报错。

    希望大家帮忙解答~

    4 条回复    2020-10-28 20:33:17 +08:00
    vsomeone
        1
    vsomeone  
    OP
       2020-10-28 19:57:22 +08:00
    我很好奇的是,在 (value: IState[key]) => void 这一部分,为什么 TS 将 key 先前的推断给忘记了,此处认定 key 的类型为 any 。
    当然更好奇的是,到底怎么写才能够达到我的目标😭
    xiangwan
        2
    xiangwan  
       2020-10-28 20:29:23 +08:00 via Android   ❤️ 1
    type Hanlder = <K extends keyof IState>(k: K) => (v: IState[K]) => void;
    vsomeone
        3
    vsomeone  
    OP
       2020-10-28 20:31:31 +08:00
    现在弄明白啦,应该这样写:

    type HandlerFactory<K extends keyof IState = keyof IState> = (key: K) => (value: IState[K]) => void;
    vsomeone
        4
    vsomeone  
    OP
       2020-10-28 20:33:17 +08:00
    二楼的写法更好一点,不需要给默认值,我的这种写法还需要给一个泛型的默认值
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2901 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:19 · PVG 08:19 · LAX 17:19 · JFK 20:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.