搜索词
合并类型
建议
如果可以合并两个类型,那就太好了。目前我能得到的最接近的是一个联合体:
type Test1 = { id: number, code: string }
type Test2 = { id: string, code: number }
type Test3 = Test1 | Test2
// This is not allowed, because x doesn't match Test1 OR Test2
export const x: Test3 = {
id: "bob",
code: "bob"
}
基本上,我想要通过合并Test1和Test2来创建以下类型:
type Test3 = { id: number | string, code: number | string }
也许可以有一个工具来合并这些类型:
type Test3 = Merge<Test1, Test2>
用例
React-Native有几个样式类型(TextStyle,ImageStyle,ViewStyle),它们在我的代码中非常有用,可以用于自动补全和类型检查。TextStyle有一个属性 fontSize: number
。我想能够重新定义TextStyle类型,以允许所有属性都有字符串值(这样我就可以使用自己的变量系统)。类似于 fontSize: "$fontSizeMD"
示例
type EImageStyle = ImageStyle | Partial<Record<keyof ImageStyle, string>>
type ETextStyle = TextStyle | Partial<Record<keyof TextStyle, string>>
type EViewStyle = ViewStyle | Partial<Record<keyof ViewStyle, string>>
type EComponentStyle = EImageStyle | ETextStyle | EViewStyle
type EComponentStyles = { [P in keyof any]: EComponentStyle }
有了合并,它看起来会是这样的:
type EImageStyle = Merge<ImageStyle, Partial<Record<keyof ImageStyle, string>>>
type ETextStyle = Merge<TextStyle, Partial<Record<keyof TextStyle, string>>>
type EViewStyle = Merge<ViewStyle, Partial<Record<keyof ViewStyle, string>>>
type EComponentStyle = EImageStyle | ETextStyle | EViewStyle
type EComponentStyles = { [P in keyof any]: EComponentStyle }
检查清单
我的建议满足以下准则:
- 这不会对现有的TypeScript/JavaScript代码造成破坏性的变化
- 这不会改变现有JavaScript代码的运行时行为
- 这可以在不根据表达式的类型发出不同的JS的情况下实现
- 这不是一个运行时特性(例如库功能、带有JavaScript输出的非ECMAScript语法等)
- 这个特性将与 TypeScript's Design Goals 的其他部分保持一致。
8条答案
按热度按时间68de4m5k1#
我不会使用“合并”这个词,因为它对不同的人意味着不同的事情。
我不确定这是否应该成为TS本身的实用程序类型。我不认为这是一个常见的用例。
你得到了属性的并集。对于每个属性,你得到了类型的并集。
有许多方法可以“合并”依赖于用例的对象。从我的个人经验来看,这里有一些。
对于属性:
对于属性的类型:
仅根据上述内容,你就有16种不同的方式来“合并”两种类型(忽略对称性)
vddsk6oq2#
命名
或许
Merge
不是一个合适的词汇,其他选择可以是:Join
、Combine
或Blend
?我选择了
Merge
,因为它与 declaration merging 感觉相关。合并的不同方式
我认为左操作数或右操作数并不重要。如果你想要进行交集操作,你可以使用
Merge
结合Omit
和/或Exclude
实用程序来实现。使用场景
我能想到的一个用例:
假设你有一个对象仓库
Repository<T>
,它有一个查询对象的函数:repository.find({ age: 20 })
。该函数通过仅接受Partial<T>
类型的参数来强制类型安全。接下来,你想让这个函数变得更智能,使其能够执行类似
repository.find({ age: { operator: "lte", value: 20 }})
的调用。你可以为此使用联合,但这样你就无法混合两者了:
aemubtdh3#
你的用例似乎不太常见或通用,我个人认为。但也许其他人会有不同的看法。(我这样说是因为我自己写了很多查询/仓库代码)
eimct9ow4#
昨天我在开发一个React-Native应用,并遇到了另一个需求。
React-Native提供了一个
Image
组件,但它没有内置的加载指示器。所以我正在开发一个RemoteImage
组件,该组件在图像完全加载之前显示加载指示器。我希望
RemoteImage
属性的source
比原始的Image
组件更智能。你应该能够指定一个直接的图像URL(字符串)或一个更复杂的ImageURISource
对象。原始的Image
组件仅支持ImageURISource
。目前,这是我的
RemoteImage
组件的Props类型:Image
组件具有更多的属性,所以如果能这样做就太好了:ergxz8rk5#
It would make sense to have a merge as it's already implemented in JS.
ztigrdn86#
为什么不使用
Omit
?j2qf4p5b7#
@alexandermckay 当有超过两个 prop 时,这并不实用。
我正在使用这个助手:
export declare type Overwrite<T, U> = Omit<T, keyof U> & U;
.brtdzjyr8#
快速尝试创建ask...请随时告诉我它的不足之处。..
添加了T2以允许指定要合并的键,可以从任一侧进行。希望对某人有所帮助。我相信更高级的开发人员可以做得更好
或者尝试使其更清晰...