Javascript 如何在typescript中键入动态加载自己成员的类

Javascript 如何在typescript中键入动态加载自己成员的类,javascript,class,typescript,types,Javascript,Class,Typescript,Types,您好,我使用的是typescript 2.1.4,我遇到了这个问题 假设我有一个对象,看起来像这样 interface IObj{ key1:ISubObj; } interface ISubObj{ exp:RegExp; method:(param:string)=>boolean } const obj:IObj={ key1: { exp: /someexp/i, method: somemethod } }

您好,我使用的是
typescript 2.1.4
,我遇到了这个问题

假设我有一个
对象
,看起来像这样

interface IObj{
    key1:ISubObj;
}
interface ISubObj{
    exp:RegExp;
    method:(param:string)=>boolean
}
const obj:IObj={
    key1: {
        exp: /someexp/i,
        method: somemethod
    }
}
function somemethod(regexp){
   return function(param){
       return regexp.test(param)
   }
} 
export class someClass {
 constructor(obj) {
    for (let k in obj) {
        this[k]=obj[k].method(obj[k].exp)
    }
    return this;
 }
}
export const Foo = new someClass(obj);
somemethod
是这样的

interface IObj{
    key1:ISubObj;
}
interface ISubObj{
    exp:RegExp;
    method:(param:string)=>boolean
}
const obj:IObj={
    key1: {
        exp: /someexp/i,
        method: somemethod
    }
}
function somemethod(regexp){
   return function(param){
       return regexp.test(param)
   }
} 
export class someClass {
 constructor(obj) {
    for (let k in obj) {
        this[k]=obj[k].method(obj[k].exp)
    }
    return this;
 }
}
export const Foo = new someClass(obj);
在类型脚本中,我创建了一个如下所示的类

interface IObj{
    key1:ISubObj;
}
interface ISubObj{
    exp:RegExp;
    method:(param:string)=>boolean
}
const obj:IObj={
    key1: {
        exp: /someexp/i,
        method: somemethod
    }
}
function somemethod(regexp){
   return function(param){
       return regexp.test(param)
   }
} 
export class someClass {
 constructor(obj) {
    for (let k in obj) {
        this[k]=obj[k].method(obj[k].exp)
    }
    return this;
 }
}
export const Foo = new someClass(obj);
我遇到的问题是,它解析为有效的
javascript
,但是,使用
Foo.key1(param)
返回类型
error
<代码>键1在Foo上不存在

我已经在类上使用了
实现someInterface
,但是只有当我使用
key1
作为可选项时,该接口才有效。我不想使用可选语法

interface someInterface {
    key1?:(param:string)=>boolean
}
export class someClass implements someInterface{...}
有没有办法在动态构造的类上创建有效类型

编辑 更正了obj未传递到构造函数的打字错误

编辑 使用@toskv-answer,我稍微改变了我的解决方案,以得到我想要的效果。但这可能不是最好的办法

interface IObj{
    key1:ISubObj;
}
interface ISubObj{
    exp:RegExp;
    method:(param:string)=>boolean
}
const obj:IObj={
    key1: {
        exp: /someexp/i,
        method: somemethod
    }
}
export interface ISomeClass{
   key1:(str:string)=>boolean;
}
export type TSomeClass<T> = {
    [P in keyof T]?=T[P]
}
export class someClass {
 constructor(obj) {
    for (let k in obj) {
        this[k]=obj[k].method(obj[k].exp)
    }
    return this;
 }
}
export const Foo:TSomeClass<ISomeClass> = new someClass(obj);
接口IObj{
键1:ISubObj;
}
接口ISubObj{
exp:RegExp;
方法:(param:string)=>布尔值
}
常量对象:IObj={
关键1:{
exp:/someexp/i,
方法:某些方法
}
}
导出接口类{
键1:(str:string)=>布尔值;
}
导出类型TSomeClass={
[P in keyof T]?=T[P]
}
导出类someClass{
建造师(obj){
for(让k在obj中){
this[k]=obj[k].方法(obj[k].exp)
}
归还这个;
}
}
导出常量Foo:TSomeClass=newsomeclass(obj);

也许有更好的方法可以做到这一点,但这里有一些东西可以开始

您可以使用2.1中添加的mappedTypes创建基于IObj接口的新类型

接口IObj{
键1:ISubObj;
}
接口ISubObj{
exp:RegExp;
方法:(param:string)=>布尔值
}
类型结果={
//必须是可选的,这样我们就可以不用任何东西初始化它
[P in keyof IObj]?:布尔值
}
阶级矿井{
//它实际上不是类的属性,但是它是类型化的
公开结果:结果={};
建造商(obj:IObj){
for(让k在obj中){
this.results[k]=obj[k].方法(obj[k].exp)
}
归还这个;
}
}
//自动完成和一切
新地雷(空)。结果。密钥1
这是操场上的一个例子

您可以在中阅读有关映射类型的更多信息

在这种情况下,这个类实际上没有意义。转换数据的函数也同样有效

函数testIObj(obj:IObj):结果{
let results:Result={};
for(让k在obj中){
结果[k]=obj[k].方法(obj[k].exp)
}
返回结果;
}
testIObj(null).key1;
这使您可以轻松地处理整个列表

如果使用方法函数将返回不同的类型,那么扩展它们也相对容易

类型结果={
//必须是可选的,这样我们就可以不用任何东西初始化它
[P in keyof IObj]?:布尔数
}

基于@toskv answer,这可能有效。除了必须更新两个接口之外,您是否发现了其他问题

interface IObj{
    key1:ISubObj;
}
interface ISubObj{
    exp:RegExp;
    method:(param:string)=>boolean
}
const obj:IObj={
    key1: {
        exp: /someexp/i,
        method: somemethod
    }
}
export interface ISomeClass{
   key1:(str:string)=>boolean;
}
export type TSomeClass<T> = {
    [P in keyof T]?=T[P]
}
export class someClass {
 constructor(obj) {
    for (let k in obj) {
        this[k]=obj[k].method(obj[k].exp)
    }
    return this;
 }
}
export const Foo:TSomeClass<ISomeClass> = new someClass(obj);
接口IObj{
键1:ISubObj;
}
接口ISubObj{
exp:RegExp;
方法:(param:string)=>布尔值
}
常量对象:IObj={
关键1:{
exp:/someexp/i,
方法:某些方法
}
}
导出接口类{
键1:(str:string)=>布尔值;
}
导出类型TSomeClass={
[P in keyof T]?=T[P]
}
导出类someClass{
建造师(obj){
for(让k在obj中){
this[k]=obj[k].方法(obj[k].exp)
}
归还这个;
}
}
导出常量Foo:TSomeClass=newsomeclass(obj);

obj是否具有特定于类型的类型,或者它可以是任何类型?@toskv obj将继续遵循相同的模式,因此它将按您看到的方式键入。我编辑以显示obj类型;顺便提一下这可能不是问题所在,但。。您实际上没有将obj传递给构造函数。:)这在您的情况下作为一个函数运行良好,但是,有两个问题。一->我试图保留简单的名称空间Foo.key1()和二->
[P in keyof IObj]?:boolean
实际上应该是`[P in keyof T]?:T[P]`以减少混乱和更加动态。但这会给其他接口带来额外的复杂性。我试图实现您的解决方案,但它不是非常可扩展的…查看类构造函数中的代码,属性值将是从IOObject接口调用方法函数的结果,并且返回布尔值,因此结果值的类型也是布尔值(除非那些方法可以返回其他的东西,否则我看不出有什么问题)。至于Foo.key1()…我想如果你不使用这个类,而只是使用一个函数来创建一些定义类型的东西(不是所有的东西都必须是类),这是可以做到的。我同意“不是所有的东西都需要是类”但我有一些计划,使用类可能有助于组织结构。这是我的方法的最简单版本…还有更多内容@toskv为什么是类?除了创建内容的方法之外,还有其他方法吗?还要记住,T[P]实际上是类型(param:string)=>布尔值。它无法正确描述实际值(即布尔值)。