无法理解为什么我的自定义类型`DefaultProps`无法与`Pick`一起使用?

时间:2020-10-25 06:21:36

标签: typescript typescript-typings

我想定义一个DefaultProps类型,它可以从给定的Undefinable类型的react组件中找到所有Props个属性,以帮助我以类型安全的方式定义defaultProps:

export type UndefinableKeys<T> = Exclude<{
  [key in keyof T]: undefined extends T[key] ? key : never
} [keyof T], undefined>;

import {UndefinableKeys} from "./UndefinableKeys";

export type DefaultProps<T> = {
  [key in UndefinableKeys<T>]: Exclude<T[key], undefined>
}

然后我定义了一个辅助函数:

type OptionalPropsBuilder<P extends object> = {
  withAll: (defaultProps: DefaultProps<P>) => DefaultProps<P>;
  withSome: <DP extends Partial<DefaultProps<P>>>(defaultProps: DP) => Pick<DefaultProps<P>, keyof DP>;
};

export default function undefinableProps<P extends object>(): OptionalPropsBuilder<P> {
  return {
    withAll: (defaultProps) => defaultProps,
    withSome: (defaultProps) => defaultProps,
  };
}

其用法如下:

type Props = {
  someProp1?: number,
  someProp2?: number
}

const allDefaultProps = undefinableProps<Props>().withAll({
  someProp1: 111,
  someProp2: 222
})

const someDefaultProps = undefinableProps<Props>().withAll({
  someProp1: 111,
  // someProp2: 222
})

但是我发现withSome方法存在编译错误,并且经过数小时的调试无法弄清原因。

  1. 为什么Pick<DefaultProps<P>, keyof DP>的{​​{1}}部分出现编译错误
  2. 我尝试将其更改为:keyof DP,但是它仍然具有相同的编译错误

1 个答案:

答案 0 :(得分:0)

通过所有映射打字稿,他们已经不知道contentContainerStyle = {{ flexGrow:1 }} DP的子集,因此P的键也必须是DP的键。

这一切都是不必要的,因为P到底是什么?这与说Pick<DefaultProps<P>, Extract<keyof DefaultProps<P>, keyof DP>>相同。只需返回DP

很明显,您的代码还没有完成,所以我花了更多的时间。

我们为对象DP定义了一个PropFiller作为一个函数,该函数接受一组有效的P并返回满足props: P的一组道具,并添加一些可选属性的子集。

P

我们用一个高阶函数来实现这一点,该函数采用type PropFiller<P extends object, DP extends Partial<DefaultProps<P>>> = (props: P) => P & DP; 的集合并返回一个defaultProps: DP函数。

PropFiller<P, DP>

我们的const createPropFiller = <P extends object, DP extends Partial<DefaultProps<P>>>(defaultProps: DP): PropFiller<P, DP> => (props: P) => ({ ...defaultProps, ...props }); 类型包括两种情况的OptionalPropsBuildercreatePropFiller要求withAll添加所有PropFiller,而DefaultProps<P>可以采用任何子集。

withSome

Typescript Playground Link