Take a look at this example:
enum ItemType {
One = 'One',
Two = 'Two',
Three = 'Three'
}
interface CommonProps {
cProp1?: string,
cProp2?: number;
}
interface OneProps extends CommonProps {
type: ItemType.One,
prop1: string;
}
interface TwoProps extends CommonProps {
type: ItemType.Two;
prop2: number;
}
interface ThreeProps extends CommonProps {
type: ItemType.Three,
prop3: string;
}
type ItemProps = OneProps | TwoProps | ThreeProps;
The code above establishes an enum for ItemType and also specifies the expected properties for each type of item object.
If I attempt to define some objects like this:
//----------------------------------------------------------------------
// This does not work, errors appear when creating an array
const obj1 = {
type: ItemType.One,
prop1: 'some value',
}
const obj2 = {
type: ItemType.Two,
prop2: 12
}
const obj3 = {
type: ItemType.Three,
prop3: 'some value'
}
const arr: Array<ItemProps> = [ obj1, obj2, obj3 ];
By hovering over obj1 in the typescript playground, you'll notice that obj1.type is typed as ItemType (and not the specific type ItemType.One), which causes TypeScript to raise an error when attempting to create an Array.
However, if I explicitly specify types like this:
//----------------------------------------------------------------------
// This works as intended
const obj4: OneProps = {
type: ItemType.One,
prop1: 'some value',
}
const obj5: TwoProps = {
type: ItemType.Two,
prop2: 12
}
const obj6: ThreeProps = {
type: ItemType.Three,
prop3: 'some value'
}
const arr2: Array<ItemProps> = [ obj4, obj5, obj6 ];
//-----------------------------------------------------------------------
TypeScript doesn't raise any issues with this approach.
It seems that TypeScript widens the types by default when inferring, but further clarification on this behavior would be greatly appreciated.