- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个受歧视的工会,例如:
type Union = { a: "foo", b: string, c: number } | {a: "bar", b: boolean }
我需要派生一个包含所有潜在属性的类型,并分配可能在
Union
的任何成员上找到的类型。 ,即使只定义在一些 - 在我的例子中:
type CollapsedUnion = {
a: "foo" | "bar",
b: string | boolean,
c: number | undefined
}
我怎样才能制作一个派生出这种折叠联合的泛型?
Omit
utility ,但对我来说不幸的是,它遗漏了每个工会成员都不存在的属性(不将它们计入
undefined
或通过
?
)。
最佳答案
我找到了一个 两个方法)!
编辑:这是一个具有两个单独类型参数的解决方案。有关具有单个联合类型参数的解决方案,请参见下方。
// The source types
type A = { a: "foo", b: string, c: number }
type B = { a: "bar", b: boolean }
// This utility lets T be indexed by any (string) key
type Indexify<T> = T & { [str: string]: undefined; }
// Where the magic happens ✨
type AllFields<T, R> = { [K in keyof (T & R) & string]: Indexify<T | R>[K] }
type Result = AllFields<A, B>
/**
* 🥳
* type Result = {
* a: "foo" | "bar";
* b: string | boolean;
* c: number | undefined;
* }
*/
工作原理
AllFields
是映射类型。映射类型的“关键”部分
[K in keyof (T & R) & string]
意味着
K
扩展联合的键
T & R
,这意味着它将是
T
中的所有键的联合。或在
R
.这是第一步。它确保我们使用所有必需的键创建一个对象。
& string
是必要的,因为它指定
K
也必须是一个字符串。无论如何,情况几乎总是如此,因为 JS 中的所有对象键都是字符串(偶数)——除了符号,但无论如何这些都是不同的鱼。
Indexify<T | R>
返回联合类型
T
和
R
但是添加了字符串索引。这意味着如果我们尝试通过
K
索引它,TS 不会抛出错误。即使
K
不存在于
T
之一中或
R
.
Indexify<T | R>[K]
意味着我们正在通过
K
索引这个 union-with-undefineds-for-string-indexes .其中,如果
K
是
T
的键,
R
或两者都将导致该键的值类型。
[string]: undefined
index 并导致值为 undefined。
// Magic as far as I'm concerned.
// Taken from https://stackoverflow.com/a/50375286/3229534
type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never
// This utility lets T be indexed by any key
type Indexify<T> = T & { [str: string]: undefined; }
// To make a type where all values are undefined, so that in AllUnionKeys<T>
// TS doesn't remove the keys whose values are incompatible, e.g. string & number
type UndefinedVals<T> = { [K in keyof T]: undefined }
// This returns a union of all keys present across all members of the union T
type AllUnionKeys<T> = keyof UnionToIntersection<UndefinedVals<T>>
// Where the (rest of the) magic happens ✨
type AllFields<T> = { [K in AllUnionKeys<T> & string]: Indexify<T>[K] }
// The source types
type A = { a: "foo", b: string, c: number }
type B = { a: "bar", b: boolean; }
type Union = A | B
type Result = AllFields<Union>
/**
* 🥳
* type Result = {
* a: "foo" | "bar";
* b: string | boolean;
* c: number | undefined;
* }
*/
我收到了
UnionToIntersection
来自@jcalz 的精彩回答。我试图理解它,但不能。无论如何,我们可以将其视为将联合类型转换为交集类型的魔术盒。这就是我们获得想要的结果所需要的全部内容。
关于typescript - 折叠一个有区别的联合——从联合派生出一个包含所有可能的键值组合的伞型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65750673/
我觉得 for(int i = 0; i < 2; i++) 和 for(int i = 0; i < 2; ++i) 不应该做同样的事情。对于第二个例子,从循环开始 i 应该等于 1 对我来说更符合
我试图牢牢掌握异常情况,以便改进我的conditional loop implementation .为此,我进行了各种实验,扔东西,看看会被抓到什么。 这个让我惊喜不已: % cat X.hs mo
我只是想回答一个问题,但我遇到了一些我不明白的事情!为什么如果我在文件中使用内联 CSS 或 CSS,如本例中的颜色,结果就不一样! 代码相同,但第一段是绿色,第二段是红色! 我真的不明白为什么? 谢
我目前正在学习 CSS 并进行试验,我偶然发现了输出中的这种差异。所以这是代码: .red-text { color: red;
"""module a.py""" test = "I am test" _test = "I am _test" __test = "I am __test" ============= ~ $ p
在向 Firestore 写入文档时,我经常看到 serverTimestamp() 标记和 new Date() 对象之间的差异不为零。 差异范围从几 秒到几十 分钟。 他们不是在做同样的事情吗?
据我了解,2.675 和 numpy.float64(2.675) 都是相同的数字。然而,round(2.675, 2) 给出 2.67,而 round(np.float64(2.675), 2) 给
问题本身的描述很简单。我正在测试 C++11 中 std::thread 库和 boost::thread 库的区别。 这些的输出: #include #include #include int
我只是想将文本文件读入 pyspark RDD,我注意到 sqlContext.read.load 之间的巨大差异和 sqlContext.read.text . s3_single_file_inp
SC.exe 和 InstallUtil 都可以安装/卸载 Windows 服务。但它们的工作方式似乎并不相同。 有什么区别? 例如,InstallUtil 失败(找不到某些文件或依赖项错误),而 S
我认为Thread对象就像是带有名称和静态Thread.CurrentThread()的抽象对象,就像访问Thread对象的方式一样。显然,这是错误的假设。。是这样的吗?
我认为Thread对象就像是带有名称和静态Thread.CurrentThread()的抽象对象,就像访问Thread对象的方式一样。显然,这是错误的假设。。是这样的吗?
我是一名优秀的程序员,十分优秀!