typescript如何解决对象动态获取属性并调用方法的类型定义?

如题
demo 如下:

var obj = {
    aaa:{
        init:function(){
            console.log('aaa')
        }
     },
     bbb:{
        init:function(){
            console.log('bbb')
        }
     }
}
function fn(type:string){
    obj[type].init()
}
fn('ccc')

报错 类型“("string")[]”上不存在属性“init”
如何定义类型,可以保证这里正常调用?

阅读 846
avatarAI BotBETA

这是一个很好的问题,你正在尝试在 TypeScript 中解决动态对象属性的类型定义问题。虽然 TypeScript 对于对象属性的类型检查非常严格,但是你仍然可以通过使用 "any" 类型来绕过这个问题。

在你的代码中,你可以将 obj 的类型定义为 any,这样就可以避免报错 类型“("string")[]”上不存在属性“init”

下面是修改后的代码:

var obj: any = {
    aaa:{
        init:function(){
            console.log('aaa')
        }
     },
     bbb:{
        init:function(){
            console.log('bbb')
        }
     }
}
function fn(type:string){
    obj[type].init()
}
fn('aaa')

然而,使用 "any" 类型可能会带来其他的类型安全问题。一个更好的解决方案是使用接口(Interface)来定义 obj 的类型。你可以创建一个接口,该接口包含以字符串为键的对象,这些对象都有 init 方法。这样,你就可以在 obj 变量上使用这个接口,而不会失去类型安全。

下面是一个使用接口的示例:

interface IInitable {
    init: Function;
}

var obj: { [key: string]: IInitable } = {
    aaa:{
        init:function(){
            console.log('aaa')
        }
     },
     bbb:{
        init:function(){
            console.log('bbb')
        }
     }
}
function fn(type:string){
    obj[type].init()
}
fn('aaa')

在这个示例中,IInitable 接口定义了一个有 init 方法的对象。然后,obj 的类型被定义为具有这个接口的对象的映射。这样,你就可以在 obj 上使用键(字符串)来调用 init 方法,而不会出现类型错误。

1 个回答
✓ 已被采纳

可以通过 typeof 获取对象 obj 的类型,再通过 keyof 获取 obj 类型中所有 key 的集合,进而确认 obj[type] 的类型。

var obj = {
  aaa: {
    init: function () {
      console.log("aaa");
    },
  },
  bbb: {
    init: function () {
      console.log("bbb");
    },
  },
};
function fn(type: keyof typeof obj) {
  obj[type].init();
}
fn("aaa");

希望有所帮助!

推荐问题
logo
Microsoft
子站问答
访问
宣传栏