typescript - 如何做一个条件泛型类型,它在未定义时有值,但在未定义和另一件事时没有值

标签 typescript typescript-generics

我有一个类型,我想用 any 将对象键定义为可选如果我不给任何值(value)

type OptionalData<T> = T extends undefined ? { data?: any } : { data: T };

export type DataObject<T = any> = {
  item?: string | null;
} & OptionalData<T>;

它可以正常工作,直到我将通用设置为 something | undefined
const data: DataObject<string | undefined> = { data: true }; // WRONG!
const data2: DataObject<string | number> = { data: true }; // CORRECT
因为我的泛型也可以扩展 undefined我将数据作为可选 any ipt
有没有办法说“当它可以扩展 any 时,它只是可选的 undefined ”左右?
Playground

最佳答案

问题
你有这些类型:

type OptionalData<T> = T extends undefined ? { data?: any } : { data: T };

export type DataObject<T = any> = {
  item?: string | null;
} & OptionalData<T>;
当您将变量输入为 DataObject 时类型参数是类型(例如 string )和 undefined 的并集您希望数据属性的类型为联合类型,但它的类型为 any :
const data: DataObject<string | undefined> = { data: ... }

// data.data should be typed as `string | undefined` however
// data.data is typed as `any`
怎么了?
TypeScript 的条件类型文档在这里很有用。它写道:

Conditional types in which the checked type is a naked type parameter are called distributive conditional types. Distributive conditional types are automatically distributed over union types during instantiation. For example, an instantiation of T extends U ? X : Y with the type argument A | B | C for T is resolved as (A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y).


Documentation on distributive conditional types
所以在你的情况下它解决了
| (string extends undefined ? { data?: any } : { data: T })
| (undefined extends undefined ? { data?: any } : { data: T })
第一个条件解析为 { data: T }第二个解析为 { data?: any } .我相信联合类型将解析为最通用的类​​型,因此该类型最终是 { data?: any } .
解决方案
这是OptionalData更新以使其按预期工作:
type OptionalData<T> = [T] extends [undefined] ? { data?: any } : { data: T };
我们刚刚包装好 Tundefined使用方括号( [] ),将它们转换为元组(或者技术上是单元组,因为它只有一个元素)。这是demo .
为什么这样做?
让我们再次回顾一下条件类型的文档,重点强调一些重要的部分:

Conditional types in which the checked type is a naked type parameter are called distributive conditional types. Distributive conditional types are automatically distributed over union types during instantiation.


当我们将这些裸类型转换为元组时,它们就不再是裸类型了。并且因为它们不再是赤裸的,它们不再被分发。

关于typescript - 如何做一个条件泛型类型,它在未定义时有值,但在未定义和另一件事时没有值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62896115/

相关文章:

angular - 在 Ionic 3 中定义模型的正确方法

javascript - "=>"符号在 ionic 框架中意味着什么?

typescript - 为什么 `T extends "A "` and ` S extends "A"`没有重叠?

typescript ,将类型从对象映射到元组

javascript - 如何通过检查 Angular 2 中的 TD 将 TH 添加到 TABLE 中?

javascript - Angular Promise.all 在超时事件中不起作用

Angular2 访问模板变量的值,

typescript - 我可以根据参数更改返回类型吗

typescript - 从 typescript 中引用自身的父对象推断窄类型

Typescript 泛型,正在使用的关键,但它也使用符号 | 进行计算数量 |字符串也是如此