I am in need of a simple function that can return either a type "Person" or a type "PersonWithSurname". I have successfully implemented this using a conditional type. However, I am facing difficulties in structuring the result without encountering TypeScript errors.
interface Person {
name: string;
}
type PersonWithSurname = Person & {
surname : string
};
type PersonNameConditional<T> = T extends true
? PersonWithSurname
: Person;
function getPerson<T extends boolean>(returnSurname: withSurname
): PersonNameConditional<T> {
if (returnSurname) {
return { name: "John", surname: "Wic-k" } as PersonNameConditional<withSurname>
} else {
return { name: "John" } as PersonNameConditional<withSurname>
}
}
// Implementation is correct ✅
The code above functions properly and IntelliSense accurately displays the returned type based on the parameter received, as demonstrated below.
const result = getPerson(true) // { name: "John", surname: "Wic-k" }: PersonWithSurname
const result = getPerson(false) // { name: "John" }: Person
// All good here ✅
However, I encounter an issue where TypeScript does not recognize the "surname" property from the response.
const requestedSurname: boolean = req.query.withSurname
let result = getPerson(requestedSurname)
if ("surname" in result)
// Validation successful ✅
result.surname = result.surname.replace(/-/g, '')
if (result.surname)
// ❌ Property "surname" does not exist on type { name : string } | PersonWithSurname
result.surname = result.surname.replace(/-/g, '')
// Desired scenario
if (requestedSurname)
// ❌ Property "surname" does not exist on type { name : string } | PersonWithSurname
result.surname = result.surname.replace(/-/g, '')
return result;
Is it not possible to effectively utilize the conditional variable in this case?