代码之家  ›  专栏  ›  技术社区  ›  ThomasReggi

基于输入选项的基本返回类型

  •  2
  • ThomasReggi  · 技术社区  · 5 年前

    一个 File 可以拥有 content 设置为 string 或者对一个 Buffer 取决于是否设置了编码选项。

    我试图重载此函数,以获得根据输入确定结果的能力。

    async function readFromFileQuery (fq: Merge<FileQuery, { encoding: FileEncodings }>): Promise<Merge<File, { content: string }>>;
    async function readFromFileQuery (fq: Merge<FileQuery, { encoding: null }>): Promise<Merge<File, { content: Buffer }>>;
    async function readFromFileQuery (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 };
    }
    
    readFromFileQuery({ path: './File.ts', encoding: FileEncodings.UTF8 }).then(r => {
        console.log(r);
    });
    

    我怎样才能用打字机实现这一点?

    1 回复  |  直到 5 年前
        1
  •  0
  •   Titian Cernicova-Dragomir    5 年前

    不确定所有类型是什么,但如果参数类型的形状在重载之间不兼容,则可以很容易地重载参数。

    这工作如期进行

    import { promisify } from "util";
    import * as fs from 'fs'
    
    
    async function readFromFileQuery(fq: Merge<FileQuery, { encoding: FileEncodings }>): Promise<Merge<File, { content: string }>>;
    async function readFromFileQuery (fq: Merge<FileQuery, { encoding?: null | undefined}>): Promise<Merge<File, { content: Buffer }>>;
    async function readFromFileQuery (fq: FileQuery): Promise<File> {
        const { path, encoding, flag } = FileQueryHandler.make(fq);
        const content = await promisify(fs.readFile)(path, { encoding, flag })
        return { path, encoding: encoding as FileEncodings, flag, content };
    }
    
    readFromFileQuery({ path: './File.ts', encoding: FileEncodings.UTF8 }).then(r => {
        console.log(r.content); // string
    });
    
    readFromFileQuery({ path: './File.ts' }).then(r => {
      console.log(r.content); // Buffer
    });
    
    readFromFileQuery({ path: './File.ts', encoding: null }).then(r => {
      console.log(r.content); // Buffer
    });
    
    // Some assumptions
    type Merge<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U 
    enum FileEncodings {
      UTF8  ="UTF8"
    }
    interface FileQuery {
      path: string,  flag?: string, encoding?: FileEncodings | null
    }
    export interface File {
      path: string,  flag?: string, encoding: string, content: Buffer | string
    }
    
    declare var FileQueryHandler: {
      make(fq: FileQuery) : FileQuery
    }