您好我使用typescript 2.1.4
并且遇到了这个问题。
想象一下,我有object
看起来像这样
interface IObj{
key1:ISubObj;
}
interface ISubObj{
exp:RegExp;
method:(param:string)=>boolean
}
const obj:IObj={
key1: {
exp: /someexp/i,
method: somemethod
}
}
和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
。 Foo上不存在key1
。
我在类上使用了implements someInterface
,但只有在我使用key1
作为可选项时,该接口才有效。我不想使用可选语法
interface someInterface {
key1?:(param:string)=>boolean
}
export class someClass implements someInterface{...}
有没有办法在动态构造的类上创建有效类型?
更正了错误,其中obj未传递给构造函数
使用@toskv回答我稍微改变了我的解决方案,以获得我想要的功能。这可能不是最好的方式
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);
答案 0 :(得分:1)
可能有更好的方法可以做到这一点,但这里有一些事情可以开始。
您可以使用2.1中添加的 mappedTypes 来创建基于IObj接口的新类型。
interface IObj {
key1: ISubObj;
}
interface ISubObj {
exp: RegExp;
method: (param: string) => boolean
}
type Result = {
// must be optional so we can initialize it with nothing
[P in keyof IObj]?: boolean
}
class Mine {
// it's not really a property of the class but hey it's typed
public results: Result = {};
constructor(obj: IObj) {
for (let k in obj) {
this.results[k] = obj[k].method(obj[k].exp)
}
return this;
}
}
// autocomplete and everything
new Mine(null).results.key1
Here是游乐场的一个例子。
您可以在2.1 release notes中了解有关映射类型的更多信息。
在这种情况下,课程并没有真正有意义。转换数据的函数也可以正常工作。
function testIObj(obj: IObj): Result {
let results: Result = {};
for (let k in obj) {
results[k] = obj[k].method(obj[k].exp)
}
return results;
}
testIObj(null).key1;
这可以让你做很好的事情,比如轻松处理整个列表。
如果方法函数返回不同的类型,它也可以相对容易地扩展以适应它们。
type Result = {
// must be optional so we can initialize it with nothing
[P in keyof IObj]?: boolean | number
}
答案 1 :(得分:0)
这可以基于@toskv回答。除了必须更新两个接口之外,您是否看到了这个问题?
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);