我有一个用于上传文件的组件,在该组件中,用户可以基于用户传递给该组件的multiple属性来上传单个文件或多个文件.用户还可以提供onChange功能,在该功能中它将接收已经上载的文件.如果用户上传一个文件,我将传递Change a File,如果用户上传多个文件,我将传递Change a File[].有没有一种方法可以声明一个基于布尔属性的接口,可以决定它应该是什么版本的函数?

export interface FilePickerProps {
  multiple?: boolean
  // something like this
  onChange: multiple ? (selectedFiles: File[]) => void : (selectedFiles: File) => void
}

我希望在传递onChange属性时,我可以接收到选定文件参数的正确类型,如果它是FileFile[]的话.

推荐答案

这种onChangemultiple的条件依赖并不能很好地用一个interface来表示.相反,使用discriminated union type会更合适,其中multiplediscriminant属性.例如:

type FilePickerProps = {
  multiple: true
  onChange: (selectedFiles: File[]) => void
} | {
  multiple?: false
  onChange: (selectedFiles: File) => void
}

现在如果multipletrue,那么onChange接受一个File的array.但如果multiplefalse或缺失或undefined,则onChange只接受单个File.

让我们来测试一下:

function foo(f: FilePickerProps, files: File[]) {
  if (f.multiple) {
    f.onChange(files); // okay
  } else {
    files.forEach(file => f.onChange(file)); // okay
  }
}

看上go 不错.编译器可以遵循这样的逻辑,即选中f.multiple会影响f.onChange的表观类型.

Playground link to code

Typescript相关问答推荐

使用FormArray在Angular中添加排序

我用相同的Redux—Toolkit查询同时呈现两个不同的组件,但使用不同的参数

根据另一个属性的值来推断属性的类型

在MessageStore对象中实现条件类型时出现TypeScrip错误

状态更新后未触发特定元素的Reaction CSS转换

编剧错误:正在等待Expect(Locator).toBeVisible()

TypeScrip:逐个 case Select 退出noUncheck kedIndexedAccess

如何在使用条件类型时使用void

有没有办法防止类型交集绕过联合类型限制?

为什么Typescript只在调用方提供显式泛型类型参数时推断此函数的返回类型?

如何扩展RxJS?

递归类型别名的Typescript 使用

将带有额外id属性的Rust struct 展平回TypeScript单个对象,以返回wasm-bindgen函数

React中的效果挂钩在依赖项更新后不会重新执行

断言同级为true或抛出错误的Typescript函数

如何使用 AWS CDK 扩展默认 ALB 控制器策略?

我是否应该在 Next.js 中的服务器组件中获取秘密数据的所有函数中使用使用服务器?

如何强制对象数组中的对象属性具有非空字符串值?

为什么 typescript 在对象合并期间无法判断无效键?

将函数签名合并到重载中