gpt4 book ai didi

typescript - 根据类中替换的扩展方法更改返回值

转载 作者:搜寻专家 更新时间:2023-10-30 21:46:13 24 4
gpt4 key购买 nike

我有一个 FileHandler 类,然后是一个扩展原始类的 FileOrNullHandler 类。

问题是 FileOrNullHandler 中从 FileHandler 继承的方法与原始类中编写的返回类型卡住。

export class FileHandler {
static async readFileFromFileQuery (fq: FileQuery): Promise<File> {
const { path, encoding, flag } = FileQueryHandler.make(fq);
const content = await promisify(fs.readFile)(path, { encoding, flag })
return { path, encoding, flag, content };
}
static async readFile (a: Path | FileQuery, b?: Omit<FileQuery, 'path'>): Promise<File> {
if (typeof a === 'string') a = FileQueryHandler.getFromPath(a, b);
return this.readFileFromFileQuery(a);
}
static async readFiles (a: (Path | FileQuery)[] | Directory, b?: Omit<FileQuery, 'path'>): Promise<File[]> {
if (a instanceof Array) return Promise.all(a.map(p => this.readFile(p, b)));
return this.readFiles(PathHandler.getFromDirectory(a), b);
}
static async readFilesFromDirectory(a: Path | FileQuery, b?: Omit<FileQuery, 'path'>): Promise<File[]> {
const ps = await DirectoryHandler.readDirectory(a);
if (typeof a === 'string') return await (this).readFiles(ps, b);
return await this.readFiles(ps, a);
}
}

export class FileOrNullHandler extends FileHandler {
static async readFileFromFileQuery (fq: FileQuery): Promise<File | null> {
return orNull(() => FileHandler.readFileFromFileQuery(fq));
}
}

我在这里看到获取正确类型的两个选项之一。

  1. 根据this设置原始方法的相对返回类型。 (可能不可能)
  2. 覆盖 FileOrNullHandler 中的方法 ReturnType

最佳答案

OOP 的一般承租人是派生类应该能够替换基类。在这种情况下,派生类无法替换基类,因为派生类具有基类的客户端不知道期望的返回类型 (null)。

蜜蜂说我们可以非常接近您想要的。

首先,我不会使用仅具有静态方法的类,我会创建一个具有实例方法的类,并声明该实例类型的 const 并将其导出供人们作为单例使用。

其次,我会将通用功能移动到通用基类中,readFileFromFileQuery 方法是抽象的,类是通用的。这允许我们插入返回 File 的版本或返回 File | 的版本。 null 不违反 Typescript(和 OOP)一致性规则

最终的解决方案看起来像这样(我填写了一些类型,不确定它们的实际定义是什么,但我添加了代码无错误所必需的最低限度):

abstract class _FileHandlerBase<T> {
abstract readFileFromFileQuery(fq: FileQuery): Promise<T>;
async readFile(a: Path | FileQuery, b?: Omit<FileQuery, 'path'>): Promise<T> {
if (typeof a === 'string') a = FileQueryHandler.getFromPath(a, b);
return this.readFileFromFileQuery(a);
}
async readFiles(a: (Path | FileQuery)[] | Directory, b?: Omit<FileQuery, 'path'>): Promise<T[]> {
if (a instanceof Array) return Promise.all(a.map(p => this.readFile(p, b)));
return this.readFiles(PathHandler.getFromDirectory(a), b);
}
async readFilesFromDirectory(a: Path | FileQuery, b?: Omit<FileQuery, 'path'>): Promise<T[]> {
const ps = await DirectoryHandler.readDirectory(a);
if (typeof a === 'string') return await (this).readFiles(ps, b);
return await this.readFiles(ps, a);
}
}
export class _FileHandler extends _FileHandlerBase<File> {
async readFileFromFileQuery(fq: FileQuery): Promise<File> {
const { path, encoding, flag } = FileQueryHandler.make(fq);
const content = await promisify(fs.readFile)(path, { encoding, flag })
return { path, encoding, flag, content };
}
}
export const FileHandler = new _FileHandler();

export class _FileOrNullHandler extends _FileHandlerBase<File | null> {
async readFileFromFileQuery(fq: FileQuery): Promise<File | null> {
return orNull(() => FileHandler.readFileFromFileQuery(fq));
}
}

export const FileOrNullHandler = new _FileOrNullHandler();

FileHandler.readFileFromFileQuery(null!) // Promise<File>
FileOrNullHandler.readFileFromFileQuery(null!) // Promise<File | null>

FileHandler.readFiles(null!) // Promise<File[]>
FileOrNullHandler.readFiles(null!) // Promise<(File | null)[]>

// Some assumptions
type Path = string;

interface FileQuery {
path: string, flag?: string, encoding?: string | null
}
export interface File {
path: string, flag?: string, encoding: string | undefined | null, content: Buffer | string
}
interface Directory {
path: string, isDir: true
}

declare var FileQueryHandler: {
make(fq: FileQuery): FileQuery
getFromPath(s: string, b?: Omit<FileQuery, 'path'>): FileQuery;
}

declare var DirectoryHandler : {
readDirectory(a: Path | FileQuery) : FileQuery[]
}
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>

function orNull<T>(fn: () => T) {
try {
return fn();
} catch (e) {
return null;
}
}
declare const PathHandler: {
getFromDirectory(d: Directory): FileQuery[];
}

关于typescript - 根据类中替换的扩展方法更改返回值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54504847/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com