网站搜索

包含特定类型的对象属性的 TypeScript 类型


我想创建一个泛型类型 CompatibleProp<T, U>,它将解析为一个字符串类型,包含 T 中所有其值类型为 U 的属性。

我想要实现的示例:

class C {
    a: number;
    b: string;
    c: Date;
}

type DatePropOfC = PropCompatible<C, Date>;  // "c"
type NumberOrStringPropOfC = PropCompatible<C, number | string>;  // "a" | "b"
type AnyPropOfC = PropCompatible<C, any>;  // same as keyof C

使用 TypeScript 2.8 的条件类型可以实现这一点吗?我尝试了几种组合,但找不到合适的方式。

答案#1

当然,你可以使用条件类型和额外的类型查询来实现这一点

type PropCompatible<T, TProp> = { [P in keyof T] : T[P] extends TProp ? P : never}[keyof T]

编辑

虽然上述类型在获取某种类型的键的联合时效果很好,但在泛型函数的上下文中,它有一个缺点,即编译器无法跟踪属性访问的类型将是给定的属性类型。要实现这种行为,我们需要以不同的方式声明限制,即只采用给定字段类型的键。我们可以使用一个额外的类型参数 K 来表示键,并要求对于 K,T 中该字段的类型为给定类型(例如 Date)

function getDate<T extends Record<K, Date>, K extends string>(t: T, k: K): Date {
    return t[k];
}

相关文章