typescript 函数只从类型中获取某些属性,具体取决于参数

f4t66c6m  于 2023-05-30  发布在  TypeScript
关注(0)|答案(1)|浏览(203)

我有一组类型/接口,它们之间有共享的属性,但有些情况下根本不使用它们,我想创建一个函数,我只能将属性的名称发送给它。
我有这些sharedProps:

export type sharedProps = {
    className?: string,
    children?: ReactNode
    size?: SIZES_TYPES,
    color?: string;
    altText?: string;
}

但有时我不使用className的例子。我想要一个函数,我可以说getProperties(['className','children']),然后它会返回一个新的类型/类,只会扩展使用这两个 prop 。他们是可选的不是我需要/想要的,我希望他们根本不可用。
有办法做到这一点吗?或者我需要为每个 prop 组合创建一个案例,并从它们扩展?
我目前的解决方案是有n个类型,包括/不包括属性,并从它们扩展,例如:

export type onlyAltText = {
    altText?: string,
}

export type onlyChildren = {
    children?: ReactNode,
}
h9a6wy2h

h9a6wy2h1#

是的你可以创建一个函数来从一个对象中拾取属性。对于类型,您可以使用Pick实用程序docs
基本上看起来就像

const pickProps = <
  T extends Record<string, unknown>,
  K extends readonly (keyof T)[]
>(
  props: T,
  keys: K
) =>
  Object.fromEntries(
    Object.entries(props).filter(([k]) => keys.includes(k))
  ) as Pick<T, K[number]>;

所以你传递给它一个对象和它的一些键数组,它会给予你一个带这些键的对象。这里使用了object from entries函数,但可以按照您的意愿实现它。我们Assert返回类型,因为这可能是最简单的类型化方法,在ts中,任何对象Map都是一个令人头痛的问题,而不Assert一些东西。大多数情况下,我不认为Assert是一个问题。
那你就可以像

const props: SharedProps = {
  altText: "text",
  color: "red",
};

const test = pickProps(props, ["className", "altText"]);
console.log(test);
// prints {"altText": "text"}

测试的类型将是Pick<SharedProps, "className" | "altText">如果你想摆脱Pick in类型,你可以把类型返回 Package 在一些扩展ts类型中,如
type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;
类型为

const test: {
    className?: string | undefined;
    altText?: string | undefined;
}

这里有一个打字脚本操场链接希望它有帮助,最好的。

相关问题