-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
type guards strangeness #7224
Comments
@Aleksey-Bykov I'm also finding that user-defined type guards often don't work the way I intuitively expect. Your example makes intuitive sense to me and I would have expected it to work. However, since you haven't started with a union type, I suspect you are working outside the bounds of what tsc can currently do with type guards. I got your example to work by changing the declaration of let value: string | (string & AsNonBlank); This seems to satisfy the compiler, and the narrowing happens as expected in both the |
Interestingly, the following version of your code does work as you expect: const enum AsUnaryFunc {}
export function isUnaryFunc(value: Function) : value is Function & AsUnaryFunc {
return value.length === 1;
}
let value: Function;
if (isUnaryFunc(value)) {
doThis(value); // expected value to be Function & AsUnaryFunc, AND IT IS
} else {
doThat(value);
}
function doThis(value: Function & AsUnaryFunc): void {
}
function doThat(value: Function) : void {
} It's the same code as yours, just with |
@yortus thanks! |
@yortus just checked with the union, it doesn't work either const enum AsNonBlank {}
export function isNonBlank(value: string | string & AsNonBlank) : value is string & AsNonBlank {
return !/^\s*$/g.test(value);
}
let value: string;
if (isNonBlank(value)) {
doThis(value); // expected value to be string & AsNonBlank, actual is *STILL* a string
} else {
doThat(value);
}
function doThis(value: string & AsNonBlank): void {
}
function doThat(value: string) : void {
} |
Sorry I wasn't clear - this one works for me: const enum AsNonBlank {}
export function isNonBlank(value: string) : value is string & AsNonBlank {
return !/^\s*$/g.test(value);
}
let value: string | (string & AsNonBlank); // <-- union here
if (isNonBlank(value)) {
doThis(value); // expected value to be string & AsNonBlank
} else {
doThat(value);
}
function doThis(value: string & AsNonBlank): void {
}
function doThat(value: string) : void {
} |
Thanks! That's a great help! |
TypeScript Version:
1.8.0
Code
Expected behavior:
value should either be
string & AsNonBlank
or there must be a message saying that the type guard is invalid or something
Actual behavior:
value is a
string
The text was updated successfully, but these errors were encountered: