Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Union types and extra properties

Tags:

typescript

Is there a way to make TypeScript compiler produce an error when a function is called with an argument that can be both of the union type cases? Example:

interface Name {
  name: string
}

interface Email {
  email: string
}

type NameOrEmail = Name | Email

function print(p: NameOrEmail) {
  console.log(p)
}

print({name: 'alice'}) // Works
print({email: 'alice'}) // Works
print({email: 'alice', name: 'alice'}) // Works, but I'd like it to fail
print({email: 'alice', age: 33}) // Doesn't work
like image 989
synapse Avatar asked Jan 03 '23 19:01

synapse


1 Answers

You can use method overloading:

interface Name {
  name: string
}

interface Email {
  email: string
}

function print(p: Name): void;
function print(p: Email): void;
function print(p: Name | Email) {
  console.log(p);
}

print({name: 'alice'}) // Works
print({email: 'alice'}) // Works
print({email: 'alice', name: 'alice'}) // Doesn't work
print({email: 'alice', age: 33}) // Doesn't work

This will basically make the signature of the method implementation "invisible" to the rest of your code.

Demo

Edit:

As pointed out by @str in strict mode the overload signatures need to specify a return type. It's still possible for the implementation to have it's return type be inferred as long as it's compatible to the return types specified in the visible signatures.

like image 140
Tao Avatar answered Jan 05 '23 08:01

Tao