键入描述替代键

时间:2017-06-20 10:38:17

标签: typescript types

我有一个看起来像这样的对象:

const object = { a: 10, an: 20 };

对象不是由我定义的,但它是我从其他地方收到的对象。此对象的键可以从以下位置获取:

const keys = {
    /**
     * A long name that describes what "a" stands for.
     */
    aReallyLongName: "a",

    /**
     * Another long name that describes what "an" stands for.
     */
    anotherReallyLongName: "an"
};

要从10获取值object,我写道:

object[keys.aReallyLongName] // 10

有没有办法以类型安全的方式使用aReallyLongName来引用object的{​​{1}}属性?

请注意,我希望使用长名称来引用短名称,而不是相反。基本上,我希望以类型安全的方式(即使作为别名)以名称a而不是aobject引用aReallyLongName ,它不必在a对象中。

我希望将keys之类的内容编译为object.aReallyLongName,并让编译器知道该值应该是object.a

也许是这样的:

number

用例

1。映射从API或库接收的数据

API可以返回缩写的键,在项目上下文中看起来不正确的键,或者需要更多描述的键。例如,API可能会返回

interface Data {
    /**
     * A long name that describes what "a" stands for.
     */
    "a" as "aReallyLongName": number;

    /**
     * Another long name that describes what "an" stands for.
     */
    "an" as "anotherReallyLongName": number;
}

object.aReallyLongName // compile to: object.a

能够定义描述此数据结构的接口,但同时使用{ "prop": { "cat": "Test", "long_description": "Lorem" } } 代替propertiesprop而不是{{1},这将是一件好事。 }和category代替cat

2。 MongoDB文档密钥的缩写

要优化MongoDB中的存储,一种方法是缩写文档的键。文档可能如下所示:

description

同样,能够描述此文档的键和值类型会很好,但同时使用long_description代替{ "p": { "n": "John Doe", "a": "Example Street" } } person代替pname代替n,而无需创建ORM图层。

1 个答案:

答案 0 :(得分:0)

您可以使用 keyof 运算符执行此操作。

它看起来像这样(我使密钥成为可索引对象,因此它的属性可以有任何名称,但如果需要,您可以指定它们):

const object = { a: 10, an: 20 };

type Keys = keyof typeof object;

const keys: { [index: string]: Keys } = {
    aReallyLongName: "a",
    anotherReallyLongName: "an"
};

如果此类型的值不是 object 的键,则会出现编译错误:

const object = { a: 10, an: 20 };

type Keys = keyof typeof object;

const keys: { [index: string]: Keys } = {
    aReallyLongName: "B",
    anotherReallyLongName: "xn"
};

您可以在手册here的高级类型部分阅读更多相关信息。

或者你可以使用一个装饰器类来定义具有与原始对象不同名称的getter和setter。

它看起来像这样。

const object: { a: number, an: number } = { a: 10, an: 20 };

class ObjectDescriptor {
    constructor(private original: typeof object) {

    }

    public get AReallyLongName() {
        return this.original.a;
    }

    public set AReallyLongName(value) {
        this.original.a = value;
    }

}

你可以像这样访问它。

let descriptor = new ObjectDescriptor(object);
descriptor.AReallyLongName;
相关问题