首页 > 解决方案 > 带接口参数的函数重载

问题描述

我正在尝试为该search()函数创建一个函数重载。此方法必须具有不同的搜索操作。

  1. 仅使用字符串类型搜索。
    • search(key: string): IPagination<Employee[]>;
  2. 搜索BasicFilter类型:
    • search(x: BasicFilter): IPagination<Employee[]>;
  3. 搜索PaginatedFilter类型:
    • search(y: PaginatedFilter): IPagination<Employee[]>;

如何在search(args: any): any;方法中检查此接口的类型?

尝试执行以下操作:

  if (typeof args === BasicFilter) {
    console.log('searched with basic filter arguments');
  }

TS 消息: 'BasicFilter' 仅指一种类型,但在此处用作值。

错误消息:未定义 BasicFilter


以下是以下代码:

接口

interface PageData {
  pageIndex: number;
  pageSize: number;
}

interface Employee {
  id: number;
  name: string;
}

interface BasicFilter {
  key: string;
  is_archived: boolean;
}

interface PaginatedFilter {
  key: string;
  is_archived: boolean;
  page: PageData;
}

interface IPagination<T> {
  length: number;
  list: T;
}

班上

class Service {

  constructor(public name) {}

    search(x: BasicFilter): IPagination<Employee[]>;
    search(y: PaginatedFilter): IPagination<Employee[]>;
    search(key: string): IPagination<Employee[]>;
    search(args: any): any {

      if (typeof args === 'string') {
        console.log('searched with keyword only');
      }

      if (typeof args === 'object') {
        console.log('searched with object arguments');
      }

    }

}

用法

const service = new Service('Serbisyo publiko');

service.search({ key: 'some key', is_archived: false });

const default_page: PageData = { pageIndex: 0, pageSize: 15 };

service.search({ key: 'some queries', is_archived: true, page: default_page });

service.search('filtering data..');

输出

searched with object arguments
searched with object arguments
searched with keyword only

演示

标签: typescript

解决方案


由于接口在运行时不存在,因此您无法使用typeof(适用于原始类型)或instanceof(适用于类)对它们进行类型保护。您可以使用in根据字段的存在来区分联合的类型保护。此外,我会为实现签名使用可能的参数类型的联合,以便类型保护正常工作并且您具有完全的类型安全性。在您的情况下,该page领域似乎是一个很好的候选人:

search(x: BasicFilter): IPagination<Employee[]>;
search(y: PaginatedFilter): IPagination<Employee[]>;
search(key: string): IPagination<Employee[]>;
search(args: BasicFilter | PaginatedFilter | string): any {

    if (typeof args === 'string') {
        console.log('searched with keyword only');
        args // is typed to string here
    }
    else if ('page' in  args) {
        console.log('searched with object arguments');
        args // is typed to PaginatedFilter here
    }else {
        args // is typed to BasicFilter here
    }
}

注意类型保护的顺序很重要,您必须首先从联合中删除字符串,因为in类型保护仅在联合中的所有类型都是对象时才起作用。


推荐阅读