Alnedru
Alnedru

Reputation: 2655

TypeScript compilation error when selecting a property which is not a part of returned interface type

I have some code using external library which retrieves data with rest from a server. It looks like this:

let value: ITypeValue & ITypeData = service.data.select('Name', 'Id', 'ChildId').get();

// ChildId is not a part of interface, but can be retrieved
forEach.value(item => (
  console.log(item.Id + ' - ' + item.Name + ' - ' + item['ChildId']);
));

Basically this code works, but if I take into account typescript, I get an error saying that item['ChildId'] is not in type ItypeValue or ITypeData, basicause this property is not part of that interface, BUT when I retrieve it it can be and it works fine, but due to typescript I get an error on compilation.

Any idea how to resolve that?

Basically I need someway to access this property... If I check during the debug mode, I see that it is there, but because it is not of type specified, typescript shows me an error.

Thanks in advance.

Upvotes: 0

Views: 104

Answers (3)

Dylan Landry
Dylan Landry

Reputation: 1290

Even if your remote resource returns the property your looking for, TypeScript may still lack a way to affirm the property is present during compilation.

You can create a new interface.


interface GetChildResponse extends ITypeValue, ITypeData {
  ChildId: string
}

let value: GetChildResponse = service.data.select('Name', 'Id', 'ChildId').get();

You can add an additional union with a third inline type definition.

let value:ITypeValue & ITypeData & { ChildId: string }= service.data.select('Name', 'Id', 'ChildId').get();
    // ChildId is not a part of interface, but can be retrieved
    forEacht.value(item => ( 
    console.log(item.Id + ' - ' + item.Name + ' - ' + item['ChildId']);
));

I wouldn't recommend this, but you could extend the ITypeData interface too.

interface ITypeData {
  ChildId string;
}

To be frank, I think your question stems from not knowing TypeScript fundamentals. I would checkout the Typescript Handbook and playing around with an online TypeScript playground like https://www.typescriptlang.org/play?#code/

To learn more about interfaces, refer to TypeScript Handbook: Interfaces.

To learn more about type unions, refer to TypeScript Handbook: Unions and Intersection Types.

Upvotes: 2

Classified
Classified

Reputation: 222

If the interface is part of the external library and you don't want to (assuming open source) fork and fix or put in a PR to the maintainers, you can tell the TS server/compiler to expect an error and ignore it.

forEach.value(item => ( 
    //@ts-expect-error
    console.log(item.Id + ' - ' + item.Name + ' - ' + item['ChildId']);
)); 

This will also throw an error if the next line does not produce a TS error.

Upvotes: 1

basarat
basarat

Reputation: 276255

The type should reflect what your data contains. So fix the types e.g.

let value:ITypeValue & ITypeData & { ChildId: string }

Upvotes: 2

Related Questions