typescript - 没有泛型的类型推断?

假设我有以下对象:

const arrayOfDifferentComponents: HowDoITypeThis = [

   {
       component: ComponentOne, // no error, keys and value types match
       inputs: {
           key1: "foo"
           key2: 1
       }
   },
   {
       component: ComponentTwo, // error, key2 should be boolean
       inputs: {
           key1: ["foo"]
           key2: 1
       } 
   }
]

class ComponentOne {
   key1!: string;
   key2!: number;
}

class ComponentTwo {
   key1!: Array<string>;
   key2!: boolean;
}

是否可以在没有泛型的情况下编写 HowDoITypeThis 类型,这样第一个数组项中的 inputs 只允许 ComponentOne 和第二项中的 inputs 只允许 ComponentTwo 的键?

澄清一下,我希望这种类型能够处理动态数量的组件和组件类型。

最佳答案

如果已知可用类型

您可以使用映射类型来创建可能配对的并集,但这有一些限制。它将使用动态数量的组件/类型对,但不适用于未知数量。

当您通过映射类型创建联合时,基本上您所做的就是创建一个键值对象类型,然后获取所有值的联合。所以 key 被丢弃了,但我们在某些时候需要某种 key 才能从 ComponentOne 进行映射。至 {component: ComponentOne; inputs: React.ComponentProps<ComponentOne>} .由于我没有看到任何类型的判别式,因此我正在努力解决这种情况下的关键问题。

(旁注:我发现您的命名令人困惑,因为您的 ComponentOne 是 props 类型而不是组件类型,所以我使用的名称更清晰。)

如果你像这样定义某种 map :

type PropTypes = {
    one: ComponentOneProps;
    two: ComponentTwoProps;
}

然后你可以像这样使用一个映射类型:

type ComponentAndProps = {
    [K in keyof PropTypes]: {
        component: React.ComponentType<PropTypes[K]>;
        inputs: PropTypes[K];
    }
}[keyof PropTypes];

这为您提供了所有有效配对的并集:

type ComponentAndProps = {
    component: React.ComponentType<ComponentOneProps>;
    inputs: ComponentOneProps;
} | {
    component: React.ComponentType<ComponentTwoProps>;
    inputs: ComponentTwoProps;
}

你的 HowDoITypeThis是一个数组 ComponentAndProps[] .如果你尝试分配 ComponentOneProps,你会得到一个大的红色错误。到 ComponentTwo组件。

TypeScript Playground Link


如果可用类型未知

如果你想让你的数组接受任何类型的组件,你需要一个不同的方法,但强制componentinput属性匹配。这确实需要泛型。它还要求您创建 arrayOfDifferentComponents通过一个函数,因为我们不能说出它的具体类型。我们需要推断它的泛型并检查所提供的数组对于该泛型是否正确。

您可以创建一个映射类型,将 prop 类型的元组映射到 component 的元组/inputs对:

type MapToPairing<T> = {
    [K in keyof T]: {
        component: React.ComponentType<T[K]>;
        inputs: T[K];
    }
}

并使用恒等函数来确保您的数组有效:

const createComponentArray = <T extends {}[]>(array: MapToPairing<T>) => array;

当您的数组包含不匹配的元素时,您确实会收到预期的错误 componentinputs属性。

TypeScript Playground Link

https://stackoverflow.com/questions/67631215/

相关文章:

r - 使用 melt 将数据合并到一个长列中

java - 我需要一个可以处理任何有效的 W3C ISO 8601 日期/时间字符串的 java.

c# - 如何将普通字符串转换为十六进制的等效字节数组?

c++ - 你能反转初始化列表中参数扩展的顺序吗?

python - 我是否需要清理/删除在部署我的 Cloud Run 实例时创建的图像?

c# - 将 MagickImage 转换为位图

powershell - 如何最好地加快 powershell 处理时间(比较对象)

python - 如何匹配该值并根据其他列字符串为它们分配一个新列

c++ - std::make_unique> 中的完美转发不是很完美

java - 整数和字符串比较在优化上有什么区别吗?