TypeScript 接口中具有不可预测字段的对象
Object with Unpredictable Fields in TypeScript Interface
我正在 Angular 中开发 Web 应用程序,并且正在对服务进行以下调用
return this.http.get<SiteContent>(this.apiUrl + this.endpoint + id)
问题是映射到 SiteContent 接口的 JSON 在其中一个内容不可预测的字段中包含一个对象。我如何在我的代码中处理这个问题才能访问 siteContent
字段中的那些字段?理想情况下,我希望能够做这样的事情
return this.http.get<SiteContent>(this.apiUrl + this.endpoint + id).subscribe((obj) => {
console.log(obj.siteContent.get("randomKey"));
})
当我尝试按键执行 get() 时,上述示例导致以下错误消息。
ERROR TypeError: obj.siteContent.get is not a function
SiteContent 界面
export interface SiteContent {
id: string;
name: string;
siteContent: Map<string,string>
}
样本JSON
{"id":"abc123","name":"name name","siteContent":{"random1":"hi","random2":"hey"}}
JavaScript 背景,不特定于 TypeScript:
JSON is a data format based on JavaScript object literal notation. When you use the JSON.parse()
method 将 JSON 字符串反序列化为 JavaScript 值,您将获得与使用 JavaScript 对象字面量相同的对象类型:
let foo = { "a": 1, "b": "two", "c": false };
console.log(foo) // { "a": 1, "b": "two", "c": false }
let bar = JSON.parse('{ "a": 1, "b": "two", "c": false }');
console.log(bar) // { "a": 1, "b": "two", "c": false }
JavaScript 中的对象是 key-value 对,其中键(通常)是字符串,但值可以是任何类型。就 JavaScript 而言,这些密钥不需要提前声明。 All objects in JavaScript are "expando" objects.
您使用点符号访问对象的 属性(如果键名是已知的有效标识符):
foo.a;
或使用方括号表示法(通常仅当键名不是有效标识符或它是某个表达式的结果时):
foo["a"];
const k = "a";
foo[k];
您不使用 get()
访问此类对象的属性。还有是a JS Map
class which stores key-value pairs and has a get()
method to retrieve such pairs. But a Map
is not the same as a plain JS object。使用Map
是有原因的,但是处理反序列化JSON一般不在其中。
因此在运行时你应该有这样的代码:
let json = JSON.parse(
'{"id":"abc123","name":"name name","siteContent":{"random1":"hi","random2":"hey"}}'
);
console.log(json.siteContent.random1); // hi
TypeScript 添加了一个静态类型系统来描述 JavaScript。它通常不会添加任何功能或改变 JavaScript 的工作方式。 An interface
type 类似于 SiteContent
是一种描述您希望在运行时与之交互的某些 JavaScript 对象形状的方式。
TypeScript 中的对象类型可以具有具有特定字符串文字键的已知属性,例如 id
或 name
。但是,将 JavaScript 对象用作 expando 对象也很常见,其中属性具有已知的值类型,但无法提前知道键。所以 TypeScript 允许你给对象类型一个 index signature。对象类型 {[k: string]: number}
表示“您可以使用 string
类型的任何键 k
对该对象进行索引,如果那里有 属性,它将是 number
。在你的例子中,你希望 siteContent
属性 是一个对象类型,它的键是任意的,但它的值是 string
s:
interface SiteContent {
id: string;
name: string;
siteContent: { [k: string]: string }
}
有了索引签名,您的代码现在可以在 TypeScript 中编译而不会出现错误:
let json = JSON.parse(
'{"id":"abc123","name":"name name","siteContent":{"random1":"hi","random2":"hey"}}'
) as SiteContent;
console.log(json.siteContent.random1); // hi
我正在 Angular 中开发 Web 应用程序,并且正在对服务进行以下调用
return this.http.get<SiteContent>(this.apiUrl + this.endpoint + id)
问题是映射到 SiteContent 接口的 JSON 在其中一个内容不可预测的字段中包含一个对象。我如何在我的代码中处理这个问题才能访问 siteContent
字段中的那些字段?理想情况下,我希望能够做这样的事情
return this.http.get<SiteContent>(this.apiUrl + this.endpoint + id).subscribe((obj) => {
console.log(obj.siteContent.get("randomKey"));
})
当我尝试按键执行 get() 时,上述示例导致以下错误消息。
ERROR TypeError: obj.siteContent.get is not a function
SiteContent 界面
export interface SiteContent {
id: string;
name: string;
siteContent: Map<string,string>
}
样本JSON
{"id":"abc123","name":"name name","siteContent":{"random1":"hi","random2":"hey"}}
JavaScript 背景,不特定于 TypeScript:
JSON is a data format based on JavaScript object literal notation. When you use the JSON.parse()
method 将 JSON 字符串反序列化为 JavaScript 值,您将获得与使用 JavaScript 对象字面量相同的对象类型:
let foo = { "a": 1, "b": "two", "c": false };
console.log(foo) // { "a": 1, "b": "two", "c": false }
let bar = JSON.parse('{ "a": 1, "b": "two", "c": false }');
console.log(bar) // { "a": 1, "b": "two", "c": false }
JavaScript 中的对象是 key-value 对,其中键(通常)是字符串,但值可以是任何类型。就 JavaScript 而言,这些密钥不需要提前声明。 All objects in JavaScript are "expando" objects.
您使用点符号访问对象的 属性(如果键名是已知的有效标识符):
foo.a;
或使用方括号表示法(通常仅当键名不是有效标识符或它是某个表达式的结果时):
foo["a"];
const k = "a";
foo[k];
您不使用 get()
访问此类对象的属性。还有是a JS Map
class which stores key-value pairs and has a get()
method to retrieve such pairs. But a Map
is not the same as a plain JS object。使用Map
是有原因的,但是处理反序列化JSON一般不在其中。
因此在运行时你应该有这样的代码:
let json = JSON.parse(
'{"id":"abc123","name":"name name","siteContent":{"random1":"hi","random2":"hey"}}'
);
console.log(json.siteContent.random1); // hi
TypeScript 添加了一个静态类型系统来描述 JavaScript。它通常不会添加任何功能或改变 JavaScript 的工作方式。 An interface
type 类似于 SiteContent
是一种描述您希望在运行时与之交互的某些 JavaScript 对象形状的方式。
TypeScript 中的对象类型可以具有具有特定字符串文字键的已知属性,例如 id
或 name
。但是,将 JavaScript 对象用作 expando 对象也很常见,其中属性具有已知的值类型,但无法提前知道键。所以 TypeScript 允许你给对象类型一个 index signature。对象类型 {[k: string]: number}
表示“您可以使用 string
类型的任何键 k
对该对象进行索引,如果那里有 属性,它将是 number
。在你的例子中,你希望 siteContent
属性 是一个对象类型,它的键是任意的,但它的值是 string
s:
interface SiteContent {
id: string;
name: string;
siteContent: { [k: string]: string }
}
有了索引签名,您的代码现在可以在 TypeScript 中编译而不会出现错误:
let json = JSON.parse(
'{"id":"abc123","name":"name name","siteContent":{"random1":"hi","random2":"hey"}}'
) as SiteContent;
console.log(json.siteContent.random1); // hi