I have the following TypeScript code:
interface qux {
foo?: string;
bar?: number | string;
}
function foobar(x: qux) { ...; something_frobz(x); ...; }
Problem: I can call foobar("hello, world")
, even though this causes something_frobz
to misbehave. I would like to catch and reject calls to foobar
with string argument at compile time, while altering the structure of qux as little as possible. What's the best way of going about this?
My own solution is to make one field required; that field has a sensible default value, and AFAIK string doesn't have any fields with the same name. That's a bit of a hack, but it works.
Another approach might be to have foobar take a union type of first-field-is-required | second-field-is-required | ... | hundredth-field-is-required
, but then I have to maintain N almost-identical copies of qux (for N > 1) and that never goes well.
Is there anything better?
Typescript version 2.2 - 2.3
To prevent passing "primitives" as a parameter, you can require it to be an object
:
function foobar(x: qux & object) { }
foobar(''); //error
foobar(1); //error
foobar({a:1}); //error
foobar({foo:'bar'}); //ok
Typescript version >= 2.4 object
constraint is not required anymore. See @dbandstra's answer for more information.