Description
TypeScript Version: 3.9.2
Search Terms:
object type inference
incorrect type inference
Expected behavior:
When I have two interfaces that extend from the same base interface I should be able to check for the existence of a property within a variable that only exists in one of the two interfaces. TypeScript will not give an error saying that the property doesn't exist on the other type when I first check for its existence.
Actual behavior:
When I have two interfaces that extend from the same base interface I am not able to check for the existence of a property within a variable that only exists in one of the two interfaces. TypeScript will give an error saying that the property doesn't exist on the other type.
Related Issues:
Code
export type ProductDescription =
| BagDescription
| BeltDescription
| ClothingDescription
| ShoeDescription;
export interface BaseDescription {
brand: string;
name: string;
partner_catalogue_number: number;
color: string;
}
export type BagDescription = BaseDescription;
export interface BeltDescription extends BaseDescription {
length: string;
length_manufacturer: string;
}
export interface ClothingDescription extends BaseDescription {
clothing_size_eu: string;
clothing_size_manufacturer: string;
}
export interface ShoeDescription extends BaseDescription {
shoe_size_eu: string;
shoe_size_manufacturer: string;
}
// a response from an API request
// unkown what description will be
const description: ProductDescription = {} as ProductDescription;
// ts error while I expect this to work
// Property 'shoe_size_eu' does not exist on type 'ProductDescription'.
// Property 'shoe_size_eu' does not exist on type 'BagDescription'
if (description.shoe_size_eu) console.log(description.shoe_size_eu)
// not a ts error
if ("shoe_size_eu" in description) console.log(description.shoe_size_eu)
Output
// a response from an API request
// unkown what ProductDescription will be
const description = {};
if (description.shoe_size_eu)
console.log(description.shoe_size_eu);
if ("shoe_size_eu" in description)
console.log(description.shoe_size_eu);
Compiler Options
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"alwaysStrict": true,
"esModuleInterop": true,
"declaration": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": 2,
"target": "ES2017",
"jsx": "React",
"module": "ESNext"
}
}
Playground Link: Provided