简体   繁体   English

如何在此泛型类型内的属性的泛型接口内定义类型

[英]How to define a type inside a generic interface for a property inside this generic type

Example:例子:

export interface Column<T> {
    field: string;
    columnFormatter?: (props: {
        value: any/** field type inside T**/; data: T; node: any
    }) => void;
}

field is the name of the property inside type T, how can I say that the value is of that type? field 是类型 T 内的属性的名称,我怎么能说该值是该类型?

export interface IPurchase {
    id: string;
    name: string;
    purchaseDate: Date;
}

let doSomethingWithMyDate: (myDate: Date) => (true);


const columns: Array<Column<IPurchase>> = [
    {
        field: "purchaseDate", /* "purchaseDate" must be inside IPurchase */
        columnFormatter: ({ value /* must identify that this is a Date */ }) => 
            doSomethingWithMyDate(value)

    }];

In order to represent the correlation between the field property and the type of the value property of the props parameter to columnFormatter , you need Column<T> to be a union type with one member for every key of T .为了表示field属性与columnFormatterprops参数的value属性类型之间的相关性,您需要Column<T>是一个联合类型,其中T的每个键都有一个成员。 For example, given your IPurchase example, you need Column<IPurchase> to be例如,给定您的IPurchase示例,您需要Column<IPurchase>

type ColumnIPurchase = {
    field: "id";
    columnFormatter?: ((props: {
        value: string;
        data: IPurchase;
        node: any;
    }) => void);
} | {
    field: "name";
    columnFormatter?: ((props: {
        value: string;
        data: IPurchase;
        node: any;
    }) => void) 
} | {
    field: "purchaseDate";
    columnFormatter?: ((props: {
        value: Date;
        data: IPurchase;
        node: any;
    }) => void);
}

This will behave as desired:这将按需要运行:

const columns: Array<Column<IPurchase>> = [
    {
        field: "purchaseDate",
        columnFormatter: ({ value }) => doSomethingWithMyDate(value)
    },
    {
        field: "name",
        columnFormatter: ({ value }) => doSomethingWithMyDate(value) // error!
        //  string isn't a Date ----------------------------> ~~~~~ 
    }
];

So that's what we want... how can we write Column<T> to do it?所以这就是我们想要的......我们如何编写Column<T>来做到这一点?


Here's one way:这是一种方法:

type Column<T> = { [K in keyof T]-?: {
    field: K;
    columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void;
} }[keyof T]

The general form of this type, {[K in keyof T]-?: F<K>}[keyof T] , is known as a distributive object type , as coined in microsoft/TypeScript#47109 ;这种类型的一般形式{[K in keyof T]-?: F<K>}[keyof T]被称为分布式对象类型,如microsoft/TypeScript#47109中所创造的; we are making a mapped type over the keys in keyof T and then immediately index into it with keyof T so as to get a union of F<K> for every key K in keyof T .我们在keyof T中的键上创建一个映射类型,然后立即使用keyof T对其进行索引,以便为 keyof T 中的每个键K获得F<K>的并keyof T

In particular here we are computing { field: K; columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void; }特别是在这里我们正在计算{ field: K; columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void; } { field: K; columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void; } { field: K; columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void; } where K is the type of the key, and T[K] is the type of the property value corresponding to that key.其中{ field: K; columnFormatter?: (props: { value: T[K]; data: T; node: any }) => void; }是键的类型, T[K] K该键对应的属性值的类型。

And you can verify that Column<IPurchase> evaluates to exactly the desired type.您可以验证Column<IPurchase>的计算结果完全符合所需的类型。

Playground link to code Playground 代码链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用泛型类型接口在接口内使参数有条件 - How to make parameter conditional inside interface with generic type interface 如何使用 keyof 属性定义通用打字稿类型? - How to define generic typescript type with keyof property? 如何基于泛型类型定义抽象属性 - How to define abstract property based on generic type 如何在动态接口中访问泛型类型属性 - How to access generic type property in dynamic interface 有没有办法用接口内的另一种类型替换泛型类型? - Is there a way to replace a generic type by another type inside an interface? 如何定义通用类型:类型为属性名称 typescript - How can I define Generic type : type as property name typescript 如何在没有类型定义的情况下定义泛型类型“具有属性”约束? - How to define generic type 'has property' constrint without type definition? 如何创建一个通用的 TypeScript 接口,该接口匹配任何类型/接口/对象,但其中的值类型有限制? - How to create a generic TypeScript interface which matches any type/interface/object with restrictions on types for values inside it? 在Typescript中的泛型类中初始化泛型 - Initializing generic type inside generic class in Typescript 通用接口内的 Typescript 函数来推断参数类型 - Typescript function inside generic interface to infer argument type
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM