如何访问用Typescript中的接口声明的属性的属性?
我正在尝试以下代码:如何访问用Typescript中的接口声明的属性的属性?,typescript,Typescript,我正在尝试以下代码: export interface IEnumElement { elem: string; text: string; val: number } export interface IIndexable<T> { [index: string]: T; } export class AdminBase { ExamStatusId: IIndexable<IEnumElement> = {
export interface IEnumElement {
elem: string;
text: string;
val: number
}
export interface IIndexable<T> {
[index: string]: T;
}
export class AdminBase {
ExamStatusId: IIndexable<IEnumElement> = {
All: {
elem: "",
text: 'Exam Status: All',
val: 0
},
Current: {
elem: "asdf",
text: 'Exam Status: Current',
val: 1
}
}
}
var x = new AdminBase();
var y = x.ExamStatusId.All;
导出接口IEnumElement{
元素:字符串;
文本:字符串;
瓦尔:号码
}
导出接口IIindexable{
[索引:字符串]:T;
}
导出类AdminBase{
ExamStatusId:IIndexable={
全部:{
元素:“,
文本:“考试状态:全部”,
瓦尔:0
},
当前:{
元素:“asdf”,
文本:“考试状态:当前”,
瓦尔:1
}
}
}
var x=新的AdminBase();
变量y=x.ExamStatusId.All;
这给了我一个错误,说:
Error 1 The property 'All' does not exist on value of type
'IIndexable<IEnumElement>'. C:\Protractor\TypeScript1.ts
错误1类型的值上不存在属性“All”
“IIndexable”。C:\dragrator\TypeScript1.ts
请注意,ExamStatusId现在只有两个属性,但以后可能会有任意数量的不同属性。这里的要点是,我们声明
ExamStatusId的类型将实现此接口IIndexable
因此,这里访问该成员的唯一方法是通过字符串索引器:
var y = x.ExamStatusId["All"];
请查看我对您上一个问题的回答。。。您将看到,我的解决方案实际上允许访问All
属性
我将再次强调TypeScript中依靠类型推断的美妙之处。您不需要显式地注释程序中的所有内容,您可以让编译器和语言服务来完成这项艰巨的工作
代码的“类型推断版本”为您提供:
- 消费点IEnumElement的类型安全性
- 如果将
ExamStatusId
属性用作IEnumElement,请键入其安全性
- 访问
All
属性
- 少手写注释
以下是完整的示例:
interface IEnumElement {
elem: string;
text: string;
val: number
}
class Exam {
private examStatusSelectId: number;
ExamStatusId = {
All: {
id: this.examStatusSelectId,
elem: '',
text: 'Exam Status: All',
val: 0
},
Current: {
id: this.examStatusSelectId,
elem: '',
text: 'Exam Status: Current',
val: 1
}
}
}
// This function must be passed an IEnumElement
function example(element: IEnumElement) {
}
var exam = new Exam();
// The compiler knows this is good
example(exam.ExamStatusId.All);
如果我要更改[index:string]的话,有没有办法改变这一点。必须在字符串中指定“All”是我试图避免的一个问题,因为如果我错误地输入“All”,我会看到问题。你认为我应该回到这个解决方案吗:我明白100%! 当我开始使用这个符号时,我想:“嘿,如果我输入ExamStatusId[“All”]
而不是ExamStatusId.All
,我就失去了类型安全性了。”但是你知道吗?用纯JSExamStatusId表示的符号。所有的也不保存。。。在JAVA或C语言的词典中。。。字典不是类型安全的。。如果你要一把钥匙。。。事后检查。。在单元测试中。。。我知道很糟糕;(…但是…最后一点注意:我们总是可以做(ExamStatusId).all
…但是小的a
而不是all
将在以后导致错误…您可以使用ExamStatusId访问它。all
具有完整的类型安全性。请参阅我的答案。我们在这里看到的是,您正在使用类型检查
。这是一种按原样定义的类型…但这不是OP情况-即使可以解决(我不知道这个问题;)。我试图解释TypeScript字典是如何工作的——例如,使用类似于IIndexable
的类型。因此,当您的示例运行时,它正在更改实现(这可能仍然是正确的);)TypeScript允许我们将大量现有的基于类的知识引入JavaScript。在可能的情况下,我们应该抛弃我们对名义类型系统的知识,接受结构类型系统。如果我们使用TypeScript是因为它提供了静态类型检查,那么任何需要魔法字符串的解决方案都不如静态类型的解决方案。同样,实现也没有什么不同,它只是由编译器而不是程序员来表达。
var y = x.ExamStatusId["All"];
interface IEnumElement {
elem: string;
text: string;
val: number
}
class Exam {
private examStatusSelectId: number;
ExamStatusId = {
All: {
id: this.examStatusSelectId,
elem: '',
text: 'Exam Status: All',
val: 0
},
Current: {
id: this.examStatusSelectId,
elem: '',
text: 'Exam Status: Current',
val: 1
}
}
}
// This function must be passed an IEnumElement
function example(element: IEnumElement) {
}
var exam = new Exam();
// The compiler knows this is good
example(exam.ExamStatusId.All);