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)=>布尔值。它无法正确描述实际值(即布尔值)。