4 ms·
Typescript couldn't actually do this for interfaces. Typescript interfaces don't exist post-compilation, and the only way to check for them would be to ensure t
by jdmichal 10y ago
Typescript couldn't actually do this for interfaces. Typescript interfaces don't exist post-compilation, and the only way to check for them would be to ensure that every expected property exists on the incoming object.
This has a very annoying side effect of never being able to exclude interfaces from a union type:
function doStuff(thing : string | SomeInterface) : void {
if (typeof(thing) === "string") {
// thing is still typed as string | SomeInterface,
// because there's no guarantee that the
// string object doesn't implement the interface.
// If SomeInterface was a class instead of an interface,
// then thing would only have the string type here.
}
}
Also, this is ignoring the fact that you would also need to check the parameter types on an incoming function, which AFAIK isn't possible at all.
- evmar 10y agoI work with TypeScript fairly closely and was surprised at your example, because I was sure that this already works. It turns out the type narrowing is actually special-cased on only some particular AST. You can see it working here, where "charAt" would not be allowed if it was still |SomeInterface: http://www.typescriptlang.org/play/#src=interface%20SomeInterface%20%7Bx%3A%20number%7D%0Afunction%20doStuff(thing%20%3A%20string%20%7C%20SomeInterface)%20%3A%20void%20%7B%0A%20%20%20%20%20%20%20%20if%20(typeof%20thing%20%3D%3D%3D%20%22string%22)%20%7B%0A%09%09%09thing.charAt(0)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%7D http://www.typescriptlang.org/play/#src=interface%20SomeInte...
- jdmichal 10y agoSo I started exploring this again today, and it ends up that what you had works, but if I parens on the typeof check, it no longer works: if (typeof(x) === "string") I opened an issue: https://github.com/Microsoft/TypeScript/issues/9391 https://github.com/Microsoft/TypeScript/issues/9391 Thanks for the help!