首页 > 解决方案 > 从由参数值确定的联合返回类型返回单个类型

问题描述

我有以下打字稿代码:

type Encoding = 'binary' | 'utf8';
type EncodingType = { binary: string, utf8: Uint8Array };

interface FS {
  readFile: <T extends Encoding>(path: string, opts?: { encoding?: T, flags?: string }) => EncodingType[T];
}

type FSMethodNames = { [K in keyof FS]: (FS)[K] extends (...args: any[]) => any ? K : never }[keyof FS];
type FSMethodArgs = { [K in FSMethodNames]: Parameters<FS[K]> };
type FSMethodReturn = { [K in FSMethodNames]: ReturnType<FS[K]> };

FS<Method extends FSMethodNames>(method: Method, ...args: FSMethodArgs[Method]): FSMethodReturn[Method];

我试图readFile根据提供的值从函数返回单一类型encoding,即stringutf8。到目前为止,它总是在返回string | Uint8Array

这是在打字稿index.d.ts中添加类型到预先存在的 JS 代码。

示例调用:

import { createFFmpeg, fetchFile } from '@ffmpeg/ffmpeg';

const ffmpeg = createFFmpeg();
const video: File;

await ffmpeg.load();

// Get video from user...

// Write the file 
ffmpeg.FS('writeFile', 'video', fetchFile(video));

// Misc. FFmpeg code to convert to gif...

// Read the result
// All three possible desired results shown
const dataA = ffmpeg.FS('readFile', 'out.gif'); // Should be string
const dataS = ffmpeg.FS('readFile', 'out.gif', { encoding: 'binary' }); // Should be string
const dataU = ffmpeg.FS('readFile', 'out.gif', { encoding: 'utf8'); // Should be Uint8Array

当前代码有效,但是dataAdataSdataU都是string | Uint8Array类型。

标签: typescript

解决方案


您尝试的方法不起作用,因为您需要两个泛型,而不是一个。FS必须是泛型methodencoding,但只有一个泛型定义。

如果您可以接受 curried API,那么您可以改用它:

declare function FS<Method extends FSMethodNames>(method: Method): FS[Method];

const string = FS('readFile')('index.js', { encoding: 'binary' });
const uintarray = FS('readFile')('index.js', { encoding: 'utf8' });
const either = FS('readFile')('index.js');

操场


推荐阅读