-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Type predicate for an optional property is not inferred #59494
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
Comments
This isn't specific to optional properties: type Obj = { prop: string | number };
function hasNumberProp(e: Obj) {
// ^? function hasNumberProp(e: Obj): boolean
return typeof e.prop === "number"; See #59088 (comment) |
Indeed, not specific to optional.
|
The gained knowledge is only about properties, it doesn't propagate to the containing object type: type Obj = { optional?: { a: number } };
function takeRequired(e: { optional: { a: number } }) {}
function test(e: Obj) {
if (e.optional) {
e.optional.a; // OK!
takeRequired(e); // not OK!
}
} That's a current design limitation that is not exclusive to type predicates. |
If this worked, it would be really useful for String.matchAll result (RegExpExecArray) with regexp with capturing groups. |
Would be great if this works. |
I Think you could use something like this to make it work. /**
* Create a new type from `T` where property `K` is non-optional.
*/
export type WithRequired<T, K extends keyof T> = T & {
[P in K]-?: T[P];
};
/**
* Type guard to signal typescript `obj` contains `name` property.
*
* @param obj Any object
* @param name Any key from obj
* @returns boolean
*/
export function isWithRequired<T extends object, U extends keyof T>(
obj: T,
name: U,
): obj is WithRequired<T, U> {
return name in obj;
}
type Obj = { optional?: { a: number } };
function takeRequired(e: { optional: { a: number } }) {}
function test(e: Obj) {
if (isWithRequired(e, "optional")) {
e.optional.a; // OK!
takeRequired(e); // OK!
}
} |
π Search Terms
inferred type predicate optional
π Version & Regression Information
β― Playground Link
https://www.typescriptlang.org/play/?ts=5.5.4#code/C4TwDgpgBA8gRgKygXigbwPZmASwwOwEMAbAfgC51DL8BXAWzggCcBfVgKFElkQCYU6LLgIkKUWvgAmEAGY58EKaygAfIdjxFilNNSh1GLdh1OzJAYxH4oOAM4xNo4gBE5CpQAoIleAgCU6BwA9MFQ4RFQAHqkHJHMEMC0zDYQAHTCWiRQAITIqJIy8opSHJwc5vhWWrYOTtpuxUp83r78gWghYTFxEQlJKVDpmc65+RLS7iVlHEA
π» Code
π Actual behavior
If a type contains an optional property, and I write a function that ensures the property is defined, the function is not inferred as a type predicate. No type narrowing happens when I use this function.
At the same time, if I rewrite the original type to be itself a union, then the type predicate is inferred, as expected.
π Expected behavior
Type predicate is inferred
Additional information about the issue
I feel it has something to do with #55257, but I'm not sure.
The text was updated successfully, but these errors were encountered: