【问题标题】:Problems accessing properties in a mapped type of generics访问映射类型的泛型中的属性时出现问题
【发布时间】:2019-12-06 09:20:47
【问题描述】:

无论好坏,我都有一个以 3 元组形式传输数据的 API:(EntityName, FieldName, Value)。还提供了id,但为了这次谈话,它可能没有实际意义。

EntityName 表示记录类型,FieldName 应该是该特定记录的键。 Value 应该是适合 FieldName 类型的值。

如果我知道EntityNameFieldName 已经有效,我正试图弄清楚如何编写一个函数,给定这个元组,可以验证Value

我已尝试以多种方式编写此代码,我相信我在下面展示的那一种是最优雅的。但是,如果不进行类型断言,我无法找到任何可行的方法,我很好奇为什么类型检查器无法确定这将起作用,考虑到 Validator 的定义方式和 @987654331 的方式@ 已定义,我希望没有投诉。

话虽如此,我还不知道我是否达到了类型检查的理论限制,或者这可能是一个错误?

export enum EntityName {
  A = 'A',
  B = 'B',
};

interface IEntityA {
  fieldA: boolean;
}

interface IEntityB {
  fieldB: string;
}

type Entity<Name extends EntityName> =
  Name extends EntityName.A ? IEntityA :
  Name extends EntityName.B ? IEntityB :
    never;

const Validator: {
  [Name in EntityName]: {
    [FieldName in keyof Entity<Name>]: (value: unknown) => value is Entity<Name>[FieldName];
  };
} = {
  [EntityName.A]: {
    fieldA: (value: unknown): value is boolean => typeof value === 'boolean',
  },
  [EntityName.B]: {
    fieldB: (value: unknown): value is string => typeof value === 'string',
  },
};

const isValueValid = <
  Name extends EntityName,
  FieldName extends keyof Entity<Name>,
>(
  entityName: Name,
  fieldName: FieldName,
  value: unknown,
): value is Entity<Name>[FieldName] => {
  return Validator[entityName][fieldName](value);
};

编译器在isValueValid 内部给了我这个错误:

Type 'FieldName' cannot be used to index type '{ A: { fieldA: (value: unknown) => value is boolean; }; B: { fieldB: (value: unknown) => value is string; }; }[Name]'.

有趣的是,传递给isValueValid 的参数类型检查正确。

【问题讨论】:

    标签: typescript typescript3.0


    【解决方案1】:

    当我尝试在 isValueValid 的主体内实例化 FieldName 类型的变量时,我遇到了一个错误,这意味着作为泛型,FieldName 可能是 keyof Entity&lt;Name&gt; 的子类型,使得某些值对于任一 @ 都无效987654328@ 或 IEntityB 就像 string | number | symbol,所以这有点不安全。 https://github.com/Microsoft/TypeScript/issues/29049

    为了简单起见,在尝试将FieldName 的类型限制为keyof Entity&lt;EntityName.A&gt; 之后,我发现一切正常,但keyof Entity&lt;Name&gt; 似乎将类型解析延迟到无法知道FieldName 的程度根据 TypeScript Designer,要么是 IEntityA | IEntityB | never,这是条件类型的设计限制。 https://github.com/Microsoft/TypeScript/issues/29225#issuecomment-451678927

    所以这也是相关的,看起来这种情况被称为“卡住”类型https://github.com/microsoft/TypeScript/issues/29413#issuecomment-455390404

    【讨论】:

      猜你喜欢
      • 2020-03-03
      • 1970-01-01
      • 2012-09-23
      • 1970-01-01
      • 1970-01-01
      • 2019-03-08
      • 1970-01-01
      • 2015-10-10
      • 1970-01-01
      相关资源
      最近更新 更多