如何在打字稿中用参数的 typeof 值覆盖泛型类型的 属性

How to override a generic type's property with an argument's typeof value in typescript

我正在尝试创建一个泛型类型检查函数来检查对象的 属性 是否具有类型。但是,如果我不需要将字段定义为参数值和类型值,那就太好了。

例如,这可行但感觉有点多余:

function isFieldPopulated<T1, T2, K extends keyof T1>(doc: T1, field: K): doc is Omit<T1, K> & Record<K, T2> {
    // check if T1[K] is a T2
    return ...;
}

if (isFieldPopulated<Post, Category, 'category'>(data, 'category')) {
    // data.category is a Category type
}

我希望不必在此处 <Post, Category, 'category'> 和此处 (data, 'category') 设置 'category'。有没有办法让 TS 知道 field 参数扩展了 keyof T1 而不必专门将 'category' 放在 <..., 'category'> 中,因为它已经作为字符串参数传递了?

更新: 这里有一个minimal working example.

因为 TypeScript 已经可以为我们正确推断 T1K,所以应该不需要显式提供 T2。看起来你只需要对象类型而不是原始类型(比如 string),所以我们可以给 T2 类型 Extract<T1[K], object>,给我们 T1[K] 中的所有对象类型:

function isFieldPopulated<T1, T2 extends Extract<T1[K], object>, K extends keyof T1>(doc: T1, field: K): doc is T1 & Record<K, T2> {

您可以验证它是否有效 here