用打字稿扩展方法

时间:2019-02-03 14:41:25

标签: javascript typescript class oop ecmascript-6

我创建了一个virtual类,该类具有读取文件或类似文件的方法。

FileHandler

这是一个带有export class FileHandler { private 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 FileHandler.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 FileHandler.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 FileHandler.readFiles(ps, b); return await FileHandler.readFiles(ps, a); } } 方法的类,因为我不需要将它们公开。

我现在想做的是扩大这堂课。

我想将static包装在try catch中,并可能返回null,类似这样,其中方法名为FileHandler.readFile,但是返回值与原始值不同。

readFile

我还想免费获得所有其他方法,因为我看到的是所有原始export class FileOrNullHandler { async readFile (a: Path | FileQuery, b?: Omit<FileQuery, 'path'>): Promise<File | null> { return orNull(() => FileHandler.readFile(a, b)); } } 都基于FileHandler

我尝试了一些将两种方法都转换为不使用FileHandler.readFile方法的方法,并且还尝试了返回类型,但是没有什么比这更简单的方法了。

我需要以下内容:

  • 两个类中的方法之间具有奇偶性
  • 让所有返回值代表类功能

我正在寻找最好的方法。

理想情况下,首先想到的是我将能够使用

  • static个调用static的方法
  • this

但是这两个东西都不存在。

我想要的是以下结果:

  • ReturnType<this.method>返回FileHandler.readFile
  • File | null返回FileHandler.readFiles
  • File[]返回FileHandler.readFilesFromDirectory
  • File[]返回FileOrNullHandler.readFile
  • (File | null)返回FileOrNullHandler.readFiles
  • (File | null)[]返回FileOrNullHandler.readFilesFromDirectory

3 个答案:

答案 0 :(得分:2)

首先,仅具有静态属性的类是没有意义的,那只是构建对象的一种非常复杂的方法:

export const FileHandler = {
   readFile (a: Path | FileQuery, b?: Omit<FileQuery, 'path'>): Promise<File> {
     // ...
   }
};

您可以按以下方式创建包装器:

 const FileOrNullHandler = Object.assign(...Object.keys(FileHandler).map(key => ({
   [key]: function(...args) {
     return orNull(() => FileHandler[key](...args);
   }
 })));

答案 1 :(得分:0)

我发现这种方法可以维护静态类,但是在FileOrNullHandler中不能正确表示类型。

export function sibling (v) {
    const staticClassName = v.toString().split ('(' || /s+/)[0].split (' ' || /s+/)[1];
    const m = {
        FileHandler,
        FileOrNullHandler
    }
    return m[staticClassName];
}

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 sibling(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 => sibling(this).readFile(p, b)));
        return sibling(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 sibling(this).readFiles(ps, b);
        return await sibling(this).readFiles(ps, a);
    }
}

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

答案 2 :(得分:0)

似乎静态类方法可以使用this并进行扩展。但是类型仍然不正确。

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));
    }
}