typescript中的默认泛型类型
所以我有一个量角器列表页面对象。该对象默认返回typescript中的默认泛型类型,typescript,protractor,Typescript,Protractor,所以我有一个量角器列表页面对象。该对象默认返回ElementFinder实例,但可以自定义为返回ComplexType实例,如下所示: class ComplexType { foo = 'foo'; constructor(public element: ElementFinder) {} } const list = new List<ComplexType>({ element: ..., type: ComplexType}); expect(list.get(0
ElementFinder
实例,但可以自定义为返回ComplexType
实例,如下所示:
class ComplexType {
foo = 'foo';
constructor(public element: ElementFinder) {}
}
const list = new List<ComplexType>({ element: ..., type: ComplexType});
expect(list.get(0).foo).toBe('foo');
类ComplexType{
foo=‘foo’;
构造函数(公共元素:ElementFinder){}
}
常量列表=新列表({element:…,type:ComplexType});
expect(list.get(0.foo).toBe('foo');
以下是页面对象定义:
import { ElementFinder } from 'protractor';
export interface ListItem<T> {
new(element: ElementFinder): T;
}
export interface ListOptions<T> {
element: ElementFinder;
selector?: string;
type?: ListItem<T>;
}
export class List<T = ElementFinder> {
public readonly element: ElementFinder;
private selector: string;
private type: (element: ElementFinder) => T;
get items() {
return this.element.$$(this.selector);
}
get length() {
return this.items.count();
}
constructor(options: ListOptions<T> | ElementFinder, selector?: string) {
if (options instanceof ElementFinder) {
this.element = options;
this.selector = selector || 'li';
this.type = (element: ElementFinder) => element;
} else {
this.element = options.element;
this.selector = options.selector || 'li';
this.type = (element: ElementFinder) => new options.type(element);
}
}
get(index: number): T {
return this.type(this.items.get(index));
}
}
从“量角器”导入{ElementFinder};
导出接口列表项{
新(元素:ElementFinder):T;
}
导出接口列表选项{
元素:ElementFinder;
选择器?:字符串;
类型?:列表项;
}
导出类列表{
公共只读元素:ElementFinder;
私有选择器:字符串;
私有类型:(element:ElementFinder)=>T;
获取项目(){
返回this.element.$$(this.selector);
}
获取长度(){
返回此.items.count();
}
构造函数(选项:ListOptions | ElementFinder,选择器?:字符串){
if(ElementFinder的选项实例){
this.element=选项;
this.selector=selector||'li';
this.type=(元素:ElementFinder)=>元素;
}否则{
this.element=options.element;
this.selector=options.selector | |“li”;
this.type=(元素:ElementFinder)=>newoptions.type(元素);
}
}
get(索引:number):T{
返回this.type(this.items.get(index));
}
}
我遇到的问题是typescript不理解t有时是ElementFinder。因此,当我返回ElementFinder的实例时,它会抱怨ElementFinder与T不匹配
我被难住了。当然这是可能的?问题是,在类中,
T
是不特定的(即使您进行一些检查,编译器也不会以任何方式缩小T
)。这意味着所有的赋值都必须适用于任何可能的T
,因为this.type=(element:ElementFinder)=>元素代码>对任何T
都不起作用,它将给出一个错误
如果我们确定这是一个误报,那么快速而肮脏的修复方法是使用类型断言:
this.type = (element: ElementFinder) => element as any;
更优雅的解决方案是将类型更改为required,并传入相应的函数:
class ComplexType {
foo = 'foo';
constructor(public element: ElementFinder) { }
}
export interface ListOptions<T> {
element: ElementFinder;
selector?: string;
type: (element: ElementFinder) => T;
}
export class List<T = ElementFinder> {
public readonly element: ElementFinder;
private selector: string;
private type: (element: ElementFinder) => T;
get items() {
return this.element.$$(this.selector);
}
get length() {
return this.items.count();
}
public static default(element: ElementFinder, selector = 'li') :ListOptions<ElementFinder>{
return {
element,
selector,
type : (e) => e
}
}
constructor(options: ListOptions<T>, selector?: string) {
this.element = options.element;
this.selector = options.selector || 'li';
this.type = options.type;
}
get(index: number): T {
return this.type(this.items.get(index));
}
}
let element!: ElementFinder;
// complex usage
const list1 = new List<ComplexType>({ element, type: e=> new ComplexType(e) });
//default usage
const list2 = new List(List.default(element));
类ComplexType{
foo=‘foo’;
构造函数(公共元素:ElementFinder){}
}
导出接口列表选项{
元素:ElementFinder;
选择器?:字符串;
类型:(元素:ElementFinder)=>T;
}
导出类列表{
公共只读元素:ElementFinder;
私有选择器:字符串;
私有类型:(element:ElementFinder)=>T;
获取项目(){
返回this.element.$$(this.selector);
}
获取长度(){
返回此.items.count();
}
公共静态默认值(元素:ElementFinder,选择器='li'):ListOptions{
返回{
元素,
选择器,
类型:(e)=>e
}
}
构造函数(选项:列表选项,选择器?:字符串){
this.element=options.element;
this.selector=options.selector | |“li”;
this.type=options.type;
}
get(索引:number):T{
返回this.type(this.items.get(index));
}
}
让元素!:元素查找器;
//复杂用法
constlist1=新列表({element,type:e=>newcomplextype(e)});
//默认用法
const list2=新列表(List.default(element));
谢谢您的解释!