I am not able to fully grasp the use of extends keyword in case of union types. Here is a code snippet explaining the confusion that I have.
class SomeClass {
someClassProp: string;
};
class SomeExtendedClass extends SomeClass {
someExtendedClassProp: string;
};
function someClassFunction<T extends SomeClass>(args: T): T {
return args;
};
let someClass: SomeClass, someExtendedClass: SomeExtendedClass;
someClassFunction(someClass);
someClassFunction(someExtendedClass); // Works just fine(case 1)
type someType = 'a' | 'b';
type someExtendedType = someType | 'c';
function someTypeFunction<T extends someType>(args: T): T {
return args;
};
let someType: someType, someExtendedType: someExtendedType;
someTypeFunction(someType);
someTypeFunction(someExtendedType); // Gives me an error(case 2)
So I was wondering why such design decisions are made and what are the implications of the same.
changing
function someTypeFunction<T extends someType>(args: T): T {return args;};
to
function someTypeFunction<T extends someExtendedType>(args: T): T {return args;};
works but I am not able to understand how this thing is actually working.
EDIT 1
type someType = 'a' | 'b';
type someOtherType = 'c';
type someUnionType = someType | someOtherType;
type someTypeCore<T extends someUnionType> = { type: T };
type someTypeObj<T extends someType> = { a: string } & someTypeCore<T>;
type someOtherTypeObj<T extends someOtherType> = { b: string, c: string } & someTypeCore<T>;
function typeAssertion<T extends someUnionType>(args: someTypeCore<T>): args is someTypeObj<T> {
return (args as someTypeObj<T>).a !== undefined; // Gives an error
};
function someTypeFunction<T extends someUnionType>(args: someTypeCore<T>): T {
if (typeAssertion(args)) {
// Do something for someTypeObj
} else {
// Do Something for someOtherTypeObj
};
return args.type;
};
How do we resolve this.