让Class <T扩展{[[key:string]:any}>实现T

时间:2019-06-07 08:06:34

标签: typescript

我有一个可注射的Class<T extends { [key: string]: any }>,其目的是获得通用对象。如:

interface Home {
  darkTheme: boolean;
  userType: number;
}

然后将我的班级注入:

constructor(myClass: Class<Home>) {}

这对于类中存在的某些方法非常有用。但是,我希望类知道其主体也将T的键作为属性。以这种方式:

const userType = this.myClass.userType // acknowledges it exists

按打字稿没问题。

TS不会对此抛出错误,并且userType将获得所需的值。但这是由于Typescript不知道该属性存在于myClass的正文中而发生的。

那我怎么告诉Typescript myClass<T>有一个正文T

我尝试过:

class myClass<T extends { [key: string extends keyof T]: any}> // nope

class myClass<T extends { [key: string]: any } implements/ extends T> // also nope

// I tried overloading
interface myClass<T extends { [key: string]: any }> {
  [key: K keyof T]: T[K]; // don't know what 'K' is;
}

interface myClass<T extends { [key: string]: any }> {
  [key: keyof T]: T[keyof T]; // interfaces don't like mapped types
}

还有更多。如果您有任何想法,我将如何实现,或者有可能,请阅读! :D谢谢。

1 个答案:

答案 0 :(得分:1)

Typescript不支持直接扩展type参数。根据您要尝试执行的操作,可以使用类型别名:

type Class<T> = T & {}
declare let myClass: Class<Home>
myClass.userType // works, and is checked
myClass.userTypes // err

或者您可以在没有显式T的情况下定义您的类,然后将其强制转换为构造函数,该构造函数返回还具有T属性的内容:

class _Class { 
    m() { }
}

const Class = _Class as (new <T>() => _Class & T);  
type Class<T> = T & _Class
let myClass = new Class<Home>()
myClass.m(); //ok
myClass.darkTheme // ok