【问题标题】:TypeScript - inferring or declaring Pick type as a functions return valueTypeScript - 将 Pick 类型推断或声明为函数返回值
【发布时间】:2019-02-12 04:32:57
【问题描述】:

考虑以下简化函数,该函数接受一个对象和该对象的属性,并返回该对象的克隆,仅具有指定的属性:

export function clonePick<T, K extends keyof T>(obj: T, prop: K) {
  const keys = Object.keys(obj).filter(k => k === prop)
  return keys.reduce(
    (clone: any, key: string) => {
      return { ...clone, [key]: obj[key as keyof T] };
    },
    {}
  );
}

这本质上与 Pick 的行为相同,除了一个值而不是一个类型,因此它的返回类型 可以表示为:

Pick<T, prop>

除了以上是无效的打字稿。但是,我们可以在调用函数时在运行前知道prop well 的值:

interface ITest {
  numProp: number;
  strProp: string;
}

const test = { numProp: 1, strProp: '1' }; // <-- type is ITest

const testClone = clonePick(test, 'numProp') // <-- type is any

我可以很容易地明确声明:

const testClone: Pick<ITest, 'numProp'> = clonePick(test, 'numProp')

但是,如果我可以将该行为作为上述函数的一部分包含在内,它会更易于维护。这可能吗?最好它可以与一组属性以及单个道具一起使用

【问题讨论】:

    标签: typescript


    【解决方案1】:

    您不会让编译器推断出对Pick 的复杂reduce 调用,它甚至不会为{ [prop]: obj[prop] } 等更简单的事情提供支持。您最好的选择是对函数的返回类型使用注释。

    export function clonePick<T, K extends keyof T>(obj: T, prop: K): Pick<T,K> {
    
      return { [prop]: obj[prop] } as any;
    }
    
    
    interface ITest {
      numProp: number;
      strProp: string;
    }
    
    const test = { numProp: 1, strProp: '1' }; // <-- type is ITest
    
    const testClone = clonePick(test, 'numProp') // 
    
    testClone.numProp
    testClone.strProp // err
    

    【讨论】:

    • 我认为签名不适用于 props 数组,但 TypeScript 巧妙地将其推断为 "numProp" | "strProp"。这正是我需要的行为!
    猜你喜欢
    • 2019-06-29
    • 2020-09-28
    • 1970-01-01
    • 2020-01-23
    • 2019-01-07
    • 2019-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多