打字稿检查是否类型 A === 类型 B |C型 [英] Typescript check if type A === type B | type C
问题描述
在一个文件中,我有这样的内容:
In one file I have something like this:
export const _all = {
a: '',
b: '',
c: '',
d: '',
e: '',
f: '',
}
type AllKeysType = typeof _all;
export type AllKey = keyof AllKeysType;
在另一个文件中,我有这样的东西:
In another file I have something like this:
export const _keep = {
a: '',
b: '',
d: '',
e: '',
}
type KeepKeysType = typeof _keep;
export type KeepKey = keyof KeepKeysType;
export const _ignore = {
c: '',
f: '',
}
type IgnoreKeysType = typeof _ignore;
export type IgnoreKey = keyof IgnoreKeysType;
我如何使用 Typescript 来断言 _all
中定义的键总是等于 _keep
和 _ignore
的并集.换句话说,AllKey
应该总是等于 KeepKey
|IgnoreKey
.
How can I use Typescript to assert that the keys defined in _all
ALWAYS is equal to the union of _keep
and _ignore
. In other words, AllKey
should always be equal to KeepKey
| IgnoreKey
.
如果开发人员通过添加新值(比如 z
)更新 _all
但忘记添加 z,我希望 Typescript 编译器给我一个错误
到 _keep
或 _ignore
中.
I want the Typescript compiler to give me an error if a developer updates _all
by adding in a new value (say z
) but forgets to add z
into either _keep
or _ignore
.
推荐答案
这可以通过定义一个接受两种类型并在输入类型相等或 时解析为
否则.然后编写一些代码,当该类型不是 true
的条件类型来实现falsetrue
时会抛出编译错误.
This is possible by defining a conditional type that accepts two types and resolves to true
when the input types are equal or false
otherwise. Then write some code that will throw a compile error when that type is not true
.
当任何一种类型更改时,您都会收到编译错误,这将确保您记住更新不同步的任何类型.当您希望收到有关不同库中类型更改的通知时,这尤其有用.
When either of the types change you'll get a compile error which will ensure you remember to update whichever type is out of sync. This is especially useful when you want to be notified about changes to a type in a different library.
例如:
type IsExact<T, U> = [T] extends [U] ? [U] extends [T] ? true : false : false;
function assert<T extends true | false>(expectTrue: T) {}
// this will throw a compile error when the two types get out of sync
assert<IsExact<AllKey, KeepKey | IgnoreKey>>(true);
更健壮的代码有点长(例如处理 any
类型),但它已汇总在我的库中 此处.
More robust code is a little longer (ex. handling the any
type), but it's rolled up in my library here.
import { assert, IsExact } from "conditional-type-checks";
// define or import AllKey, KeepKey, IgnoreKey
assert<IsExact<AllKey, KeepKey | IgnoreKey>>(true);
另一种选择
另一种不太好的方法是创建两种类型的两个对象并将它们分配给彼此.
Another not so nice way of doing this is to create two objects of the two types and assign them to each other.
() => {
let allKeys: AllKey;
let otherKeys: KeepKey | IgnoreKey;
// do this in lambdas to prevent the first assignment from changing
// the type of the variable being assigned to
() => allKeys = otherKeys;
() => otherKeys = allKeys;
};
这篇关于打字稿检查是否类型 A === 类型 B |C型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!