如何为包含键/值对以及嵌套对象的对象/数组定义接口?



我正在键入一个本地化库,我的目标是让它强类型化(因为它将在多个角度应用程序中重用),同时 - 向后兼容,这样我们就不必重写所有现有的本地化文件。

但是,上述本地化文件的结构让我有点头疼。每个示例:

{
'any-random-key': 'This is a string',
'another-random-key': {
'random-key': 'This is a string'
},
'yet-another-random-key': {
'random-key-2': 'This is a string',
'random-key-3': {
'random-key-4': 'This is a string',
'random-key-5': {
'random-key-6': 'This is a string'
}
}
},
'and-yet-another-random-key': {
'random-key-6': {
'random-key-7': {
'random-key-8': 'This is a string'
},
'random-key-9': 'This is a string'
}
}
}

现在 - 我想我可以说该服务接受translations: anytranslations: object- 但这对我来说有点太随机了(没有双关语)。

所以我尝试使用两种不同的接口:

export interface ITranslation {
[s: string]: string;
}
export interface ITranslations {
[s: string]: ITranslation;
}

然而,这any-random-key说:Type 'string' is not assignable to type 'ITranslation'

所以我调整了我的ITranslations界面,使其成为

export interface ITranslations {
[s: string]: ITranslation | string;
}

它修复了上述错误,但在'and-yet-another-random-key'上引入了一个新错误,说Property ''and-yet-another-random-key'' is incompatible with index signature.

在这一点上,我有点难倒。我试图实现的目标(遗留结构的强类型)根本不合理吗?

对于任意级别的嵌套(换句话说,您的数据对象可以根据需要深度为任意多个级别),您可以简单地自引用接口,如下所示:

/** @interface */
export interface ITranslations {
[s: string]: ITranslations | string;
}

在 TypeScript 操场上查看上面的例子。


如果你只想允许 3 级深度嵌套,那么接口必须很详细:TypeScript 不允许你定义"深度"(即嵌套程度):

/** @interface */
export interface ITranslations<T = string> {
[s: string]: T | string;
}
/** @type */
export type ITranslationsMax3Levels = ITranslations<ITranslations<ITranslations<ITranslations>>>;
const data: ITranslationsMax3Levels = { ... }

在 TypeScript 操场上查看上面的例子。

似乎解决方案比我敢于希望的要容易:

export interface ITranslations {
[s: string]: ITranslations | ITranslation | string;
}

最新更新