【问题标题】:Typescript check if type A === type B | type C打字稿检查类型 A === 类型 B | C型
【发布时间】:2019-07-29 11:34:44
【问题描述】:

在一个文件中我有这样的内容:

export const _all = {
  a: '',
  b: '',
  c: '',
  d: '',
  e: '',
  f: '',
}
type AllKeysType = typeof _all;
export type AllKey = keyof AllKeysType;

在另一个文件中我有这样的东西:

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.

如果开发人员通过添加新值(例如 z)更新 _all 但忘记将 z 添加到 _keep_ignore 中,我希望 Typescript 编译器给我一个错误。

【问题讨论】:

    标签: typescript types assert typeof keyof


    【解决方案1】:

    这可以通过定义一个条件类型来实现,该类型接受两种类型并在输入类型相等时解析为true,否则解析为false。然后写一些代码,当该类型不是true时会抛出编译错误。

    当任何一种类型发生变化时,您都会收到编译错误,这将确保您记得更新不同步的类型。当您希望收到有关不同库中类型更改的通知时,这尤其有用。

    例如:

    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 类型),但它已汇总在我的库中 here

    import { assert, IsExact } from "conditional-type-checks";
    
    // define or import AllKey, KeepKey, IgnoreKey
    
    assert<IsExact<AllKey, KeepKey | IgnoreKey>>(true);
    

    另一种选择

    另一种不太好的方法是创建两种类型的两个对象并将它们相互分配。

    () => {
      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;
    };
    

    【讨论】:

    • 非常感谢,assert函数很好用!
    猜你喜欢
    • 2019-09-25
    • 2018-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-27
    • 2021-01-09
    • 2021-08-25
    • 2021-11-26
    相关资源
    最近更新 更多