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

ts 中,访问对象的属性,如何获得更准确的类型

  •  
  •   tobemaster · 2022-01-10 18:21:19 +08:00 · 1561 次点击
    这是一个创建于 1027 天前的主题,其中的信息可能已经有所发展或是发生改变。
    interface MyProps {
      x: number;
      y: string;
    }
    
    const myVar: MyProps = {
      x: 1,
      y: '2',
    };
    
    function getMyValue(prop?: keyof MyProps) {
      if (prop) {
        return myVar[prop];
      }
      return myVar;
    }
    
    const x = getMyValue('x');
    const y = getMyValue('y');
    const val = getMyValue();
    

    这个时候,x 的类型 is 'string' | 'number' | MyProps, 但是我预期的类型 x is 'number'. y is 'string', and val is MyProps. 怎么做比较优雅

    5 条回复    2022-01-12 11:21:49 +08:00
    wunonglin
        1
    wunonglin  
       2022-01-10 18:32:11 +08:00
    就不应该有这个 getMyValue 方法。直接 myVar.x 不就是 number 了么?直接 value = object.key 。还是说你有什么特殊场景
    chouchoui
        2
    chouchoui  
       2022-01-10 18:38:24 +08:00   ❤️ 1
    function getMyValue<T extends keyof MyProps>(prop: T): MyProps[T];
    function getMyValue(): MyProps;
    function getMyValue<T extends keyof MyProps>(prop?: T) {
    if (prop) {
    return myVar[prop];
    }
    return myVar;
    }
    tobemaster
        3
    tobemaster  
    OP
       2022-01-10 18:43:22 +08:00
    @wunonglin 这里是被我简化了,我的场景是获取 React 的 context 的值, 参考 2 楼的回答,已经解决了

    ```
    import * as React from 'react';
    import { ConfigConsumerProps, ConfigContext } from '../ConfigContext';

    type ConfigConsumerKeys = keyof ConfigConsumerProps;

    type ConfigType = Exclude<
    ConfigConsumerKeys,
    'rootPrefixCls' | 'iconPrefixCls' | 'locale' | 'theme'
    >;

    export function useComponentConfig(): ConfigConsumerProps;
    export function useComponentConfig<T extends ConfigType>(
    type: T
    ): ConfigConsumerProps[T];

    export function useComponentConfig<T extends ConfigType = ConfigType>(
    configType?: T
    ): ConfigConsumerProps[T] | ConfigConsumerProps {
    const config = React.useContext(ConfigContext);
    if (configType) {
    return config[configType];
    }
    return config;
    }
    ```
    tobemaster
        4
    tobemaster  
    OP
       2022-01-10 18:43:43 +08:00
    @chouchoui 正常工作,谢谢
    fifa666
        5
    fifa666  
       2022-01-12 11:21:49 +08:00
    interface MyProps {
    x: number;
    y: string;
    }

    type getMyValue<P, T> = P extends keyof T ? T[P] : T

    type x = getMyValue<'x', MyProps>;
    type y = getMyValue<'y', MyProps>;
    type val = getMyValue<unknown, MyProps>;
    这样也可以
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   957 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 20:25 · PVG 04:25 · LAX 13:25 · JFK 16:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.