简体   繁体   English

打字稿检查类型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;

How can I use Typescript to assert that the keys defined in _all ALWAYS is equal to the union of _keep and _ignore . 如何使用Typescript断言_all ALWAYS中定义的键等于_keep_ignore_ignore In other words, AllKey should always be equal to KeepKey | 换句话说, AllKey应该始终等于KeepKey | IgnoreKey . IgnoreKey

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 . 如果开发人员通过添加新值(比如z )来更新_all但是忘记将z添加到_keep_ignore我希望Typescript编译器给我一个错误。

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. 这可以通过定义接受两种类型的条件类型,并在输入类型相等时解析为true ,否则解析为false Then write some code that will throw a compile error when that type is not true . 然后编写一些代码,当该类型不为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. 当您希望收到有关其他库中类型更改的通知时,此功能尤其有用。

For example: 例如:

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);

More robust code is a little longer (ex. handling the any type), but it's rolled up in my library here . 更强大的代码是一个长一点(例如,处理any类型),但它卷起在我的图书馆在这里

import { assert, IsExact } from "conditional-type-checks";

// define or import AllKey, KeepKey, IgnoreKey

assert<IsExact<AllKey, KeepKey | IgnoreKey>>(true);

Another Option 另外一个选项

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;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM