I am trying to understand how TypeScript conditional type works. Here is my code. There are type errors:
interface MyType {
name: string;
}
const testFu
The function TestFunc
in your code is supposed to return string
in every case. I think it is a kind of typo. Let's fix it and go on.
Later I came up with a more safe solution (I leave my old answer at the bottom). It is better to use overloading. In an overloading you describe the conditional logic and in the function you use union types.
interface MyType {
name: string;
}
function testFunc(
what: T
): T extends MyType ? string : MyType;
function testFunc(what: MyType | string): MyType | string {
if (typeof what === 'object') {
return what.name;
}
return { name: what };
}
The old answer:
interface MyType {
name: string;
}
type TestFunc = (what: T) => T extends MyType ? string : MyType;
const testFunc: TestFunc = (what: any) => {
if (typeof what === 'object') {
return what.name;
}
return { name: what };
};
Or if you prefer to define the type inline:
interface MyType {
name: string;
}
const testFunc: (what: T) =>
T extends MyType ? string : MyType =
(what: any) => {
if (typeof what === 'object') {
return what.name;
}
return { name: what };
};
Typescript compiler will handle it like this:
const a1: MyType = testFunc({ name: 'foo' }); // Type 'string' is not assignable to type 'MyType'.
const a2: MyType = testFunc({ name: 1 }); // Error: Argument of type '{ name: number; }'
// is not assignable to parameter of type 'string | MyType'
const a3: string = testFunc({ name: 'foo' }); // Ok
const a4: string = testFunc('foo'); // Error: Type 'MyType' is not assignable to type 'string'.
const a5: MyType = testFunc('foo'); // Ok