Samantha J T Star
Samantha J T Star

Reputation: 32838

How can I access a property of a property declared with an interface in Typescript?

I am trying this code:

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;

It's giving me an error saying:

Error   1   The property 'All' does not exist on value of type 
'IIndexable<IEnumElement>'. C:\Protractor\TypeScript1.ts

Note that ExamStatusId has just two properties now but there could be any number of different properties later on.

Upvotes: 0

Views: 125

Answers (2)

Fenton
Fenton

Reputation: 251242

Please check out my answer to your previous question... you'll see that my solution does in fact allow access to the All property.

Can I define an interface for every property of an object just the one time?

Once again, I'll stress the beauty within TypeScript of leaning on type inference. You don't need to explicitly annotate everything in your program, you can let the compiler and language service do the hard work.

The "type inference version" of your code gives you:

  • Type safety for IEnumElement at the point of consumption
  • Type safety for ExamStatusId property if you use it as an IEnumElement
  • Access to the All property
  • Less hand-written annotations

Here is the full example:

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);

Upvotes: 1

Radim K&#246;hler
Radim K&#246;hler

Reputation: 123901

The point here, is that we declare the type of ExamStatusId to be implementing this interface IIndexable<IEnumElement>

ExamStatusId: IIndexable<IEnumElement>

And we also declared, that the IIndexable<IEnumElement> is having string key and element of type T:

export interface IIndexable<T> {
    [index: string]: T;
} 

So, the only way here how to acces that member is via string indexer:

var y = x.ExamStatusId["All"];

Upvotes: 1

Related Questions