如何在打字稿中用参数的 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 已经可以为我们正确推断 T1
和 K
,所以应该不需要显式提供 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。
我正在尝试创建一个泛型类型检查函数来检查对象的 属性 是否具有类型。但是,如果我不需要将字段定义为参数值和类型值,那就太好了。
例如,这可行但感觉有点多余:
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 已经可以为我们正确推断 T1
和 K
,所以应该不需要显式提供 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。