将索引签名与方法配合使用-Typescript 3.5

时间:2019-10-11 18:57:09

标签: typescript

interface Keys {
  [key: string]: any
}

const obj: Keys = {
  trimDescription(text: string, length: number): string {
    return text.length > length ? text.substring(0, length - 3) + '...' : text
  }
}

Object.keys(obj).forEach(key => {
  console.log(obj[key])
})

我在界面中使用any,但这不是使用TS的正确方法,如何在我的界面中描述我的方法(我打算再增加一些)?

2 个答案:

答案 0 :(得分:1)

这完全取决于您需要的界面。通常是用一个接口表示对象的形状,因此显式地键入所有方法,然后让对象“实现”它:

interface Keys {
    trimDescription(text: string, length: number): string;
    makeUppercase(description: string, active: boolean): string;
}

const obj: Keys = {
    trimDescription(text, length) {
        return text.length > length ? text.substring(0, length - 3) + '...' : text;
    },

    makeUppercase(description, active) {
        // ...
    },
};

(Object.keys(obj) as (keyof Keys)[]).forEach(key => {
    console.log(obj[key]);
});

我想索引签名不是您想要的。除非您需要某种“袋”某种类型的属性,否则不需要索引签名,那么您所有的属性都必须符合该签名。

还可以从创建的对象推断类型:

const obj = {
    trimDescription(text: string, length: number): string {
        return text.length > length ? text.substring(0, length - 3) + '...' : text;
    },

    makeUppercase(description: string, active: boolean): string {
        // ...
    },
};

// Inferred from the implict shape of the object
type Keys = typeof obj;

(Object.keys(obj) as (keyof Keys)[]).forEach(key => {
    console.log(obj[key]);
});

playground

也许您应该考虑使用一个类。

Object.keys()的问题在于它返回类型Array<string>,但是string无法为没有索引签名的对象建立索引。原理请参见here。给定类型为T的对象的键的类型为keyof T,因此使用(Object.keys(obj) as (keyof Keys)[])告诉TypeScript将键数组“解释”为类型Array<keyof Keys>,所以它可以索引对象,例如obj[key]。主要问题是,在某些情况下,对象可以具有除其类型表示的属性之外的其他可枚举属性,因此在实践中,Object.keys()给出的每个键都不是keyof T类型是不正确的;但是,如果确定对象没有其他属性,例如在从对象文字创建obj的示例中,则断言是安全的,但是您需要显式地表示。

答案 1 :(得分:0)

interface Keys {
    [key: string]: (text: string, length: number) => string;
}

const obj: Keys = {
    trimDescription(text: string, length: number): string {
        return text.length > length ? text.substring(0, length - 3) + '...' : text
    }
}

Object.keys(obj).forEach(key => {
    console.log(obj[key])
})