TypeScript -在泛型函数中将条件类型与枚举一起使用时出错

ecbunoof  于 2023-05-30  发布在  TypeScript
关注(0)|答案(1)|浏览(177)

我在TypeScript函数中使用条件类型时遇到错误,该函数具有基于枚举的条件。
枚举:

export enum FactoryResult {
  INTERNAL_FORMALITY_CREATED_WITH_DOCS,
  INTERNAL_FORMALITY_INVALID_DOCS,
  INTERNAL_FORMALITY_MISSING_DOCS,
}

下面是函数的开始:

public fromData<T extends FactoryResult>(
  data: FormalityCreationDTO,
  filesAttachments: FileAttachment[],
): {
  factoryResult: T;
  formality: T extends FactoryResult.INTERNAL_FORMALITY_MISSING_DOCS ? never : formality;
  invalidDocuments: T extends FactoryResult.INTERNAL_FORMALITY_MISSING_DOCS ? never : FileAttachment[];
} {
   if (filesAttachments.length < NumberOfFilesRequiredForCreation.TEST) {
  return {
    factoryResult: FactoryResult.INTERNAL_FORMALITY_MISSING_DOCS, // <= error
  };
...
}}

在这个函数中,我使用了一个条件类型,根据T的值来确定inpiFormalityinvalidDocuments的类型。如果TFactoryResult枚举的特定键,则两个属性都应该是never类型,表示它们可能不会返回。
函数的第一个条件中的错误:

TS2322: Type 'FactoryResult.INTERNAL_FORMALITY_MISSING_DOCS' is not assignable to type 'T'.   'FactoryResult.INTERNAL_FORMALITY_MISSING_DOCS' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'FactoryResult'.

我正在试图理解为什么会出现这个错误。谢谢你的帮助!

aelbi1ox

aelbi1ox1#

赋值给一个条件类型(返回一个特定类型的值是一个赋值),TypeScript真的很难允许。它有一个非常困难的时间试图弄清楚哪一方的条件是正确的使用。
但在绝大多数情况下,你不需要。
这里T只在返回类型中被引用,所以它 * 不能 * 从输入中推断出来。
根据运行时值(filesAttachments数组中的项数),您将返回两个值形状之一。所以你不知道编译时会返回什么。这意味着泛型类型参数对您没有任何帮助。
所以事实证明,这根本不是一般的。它只是一个函数,返回一个有区别的可能性的联合。
创建函数可以返回的类型:

type MissingDocsResult = {
  factoryResult: FactoryResult.INTERNAL_FORMALITY_MISSING_DOCS
}

type OtherResult = {
  factoryResult: FactoryResult.INTERNAL_FORMALITY_CREATED_WITH_DOCS | FactoryResult.INTERNAL_FORMALITY_INVALID_DOCS
  formality: string // use a type for whatever this is
  invalidDocuments: FileAttachment[]
}

然后让你的函数返回:

class A {
  public fromData<T extends FactoryResult>(
    data: FormalityCreationDTO,
    filesAttachments: FileAttachment[],
  ): MissingDocsResult | OtherResult { // function returns either shape
    if (filesAttachments.length < NumberOfFilesRequiredForCreation.TEST) {
      return { // works fine
        factoryResult: FactoryResult.INTERNAL_FORMALITY_MISSING_DOCS,
      }
    }

    return { // works fine
      factoryResult: FactoryResult.INTERNAL_FORMALITY_INVALID_DOCS,
      formality: 'a formality here',
      invalidDocuments: filesAttachments,
    }
  }
}

见操场

相关问题