Closed
Description
TypeScript Version: 3.7.2
Search Terms: discriminating union, types incompatible, not assignable
Expected behavior:
The code should compile.
Actual behavior:
Related Issues: None found yet.
Code
Note that this is a reduced example. My real-world use case uses the schema-dts
json-ld library which provides the Vehicle
/Car
/etc. types.
type Vehicle =
| ({
'@type': 'Vehicle'
} & {
speed?: number
})
| ({
'@type': 'Car'
} & {
speed?: number
} & {
roofLoad?: number
})
let type = 'Car' as 'Vehicle' | 'Car'
// TypeScript error: Type '{ '@type': "Vehicle" | "Car"; }' is not assignable to type 'Vehicle'. Types of property ''@type'' are incompatible. Type '"Vehicle"' is not assignable to type '"Car"'.
const v: Vehicle = {
'@type': type,
}
Interestingly, modifying the Vehicle
type would make it compile (but I cannot do that in my real-world project because the types are provided by the schema-dts
json-ld library):
type Vehicle =
| ({
'@type': 'Vehicle'
speed?: number
})
| ({
'@type': 'Car'
speed?: number
roofLoad?: number
})
let type = 'Car' as 'Vehicle' | 'Car'
// TypeScript error: Type '{ '@type': "Vehicle" | "Car"; }' is not assignable to type 'Vehicle'. Types of property ''@type'' are incompatible. Type '"Vehicle"' is not assignable to type '"Car"'.
const v: Vehicle = {
'@type': type,
}
Compiler Options
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"useDefineForClassFields": false,
"alwaysStrict": true,
"allowUnreachableCode": false,
"allowUnusedLabels": false,
"downlevelIteration": false,
"noEmitHelpers": false,
"noLib": false,
"noStrictGenericChecks": false,
"noUnusedLocals": false,
"noUnusedParameters": false,
"esModuleInterop": true,
"preserveConstEnums": false,
"removeComments": false,
"skipLibCheck": false,
"checkJs": false,
"allowJs": false,
"declaration": true,
"experimentalDecorators": false,
"emitDecoratorMetadata": false,
"target": "ES2017",
"module": "ESNext"
}
}
Playground Link: Provided