我正在尝试使SELECT_CATALOG_ROLE
函数重载。此方法必须具有不同的搜索操作。
search()
search(key: string): IPagination<Employee[]>;
类型的搜索:
BasicFilter
search(x: BasicFilter): IPagination<Employee[]>;
类型的搜索:
PaginatedFilter
如何使用search(y: PaginatedFilter): IPagination<Employee[]>;
方法检查此接口的类型?
尝试执行以下操作:
search(args: any): any;
TS消息:“ BasicFilter”仅引用一种类型,但在此处用作值。
错误消息:未定义BasicFilter
以下是以下代码:
界面
if (typeof args === BasicFilter) {
console.log('searched with basic filter arguments');
}
班级
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..');
答案 0 :(得分:2)
由于接口在运行时不存在,因此无法使用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
类型保护仅在联合中的所有类型都是对象时才起作用。>
答案 1 :(得分:0)
从您的问题中可以看出,当前通过不同的界面(例如基本过滤器,分页过滤器等)和字符串显示了三种搜索可能性。 Tommorow可能会发生这种情况,您可能需要提出另一个具有不同搜索过滤器的界面。
要提供可扩展性和有助于您实现OCP的通用搜索术语,请让您的所有接口都来自另一个虚拟接口(如IFilterCriteria)。这意味着基本过滤器,分页过滤器现在将从IFilterCriteria派生。另外,为了提供基于Strign的搜索创建器,还将从IFilterCriteria派生另一个名为StringFilter的接口。
IFilterCriteria接口将定义为:
interface IFilterCriteria {
}
这意味着它不处于任何状态。这只是一个标记界面
BasicFilter接口现在将定义为
interface BasicFilter extends IFilterCriteria {
key: string;
is_archived: boolean;
}
类似地,我们可以修改
的定义interface PaginatedFilter extends IFilterCriteria {
key: string;
is_archived: boolean;
page: PageData;
}
因此,这为所有当前和将来的过滤可能性提供了共同点。
现在搜索功能变得更加安全,其签名将为:
search(args: IFilterCriteria): any;
由于现在搜索将这个IFilterCriteria接口作为参数,因此可以安全地在函数体内进行类型转换和检查