-
Notifications
You must be signed in to change notification settings - Fork 2.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
core: refine typing of isObject<T>
#12259
Conversation
The template parameter for `isObject` is currently used to force cast the value passed to the function, although there is no guarantee nor check done to ensure that this is really the case. This commit updates the typings so that the type passed to `isObject` is used to guide TypeScript during subsequent field type checking, assuming each field value is `unknown` and must also be type checked. Example: ```ts interface MyType { foo: string } const unknownValue: unknown = { foo: 2 }; if (isObject<MyType>(unknownValue)) { // We enter this branch because `unknownValue` is indeed an object, // and TypeScript now knows we might want to access the `foo` field // from our interface. But we can't yet assume to know the type of // `foo`, so it is still typed as `unknown` and we must check: if (isString(unknownValue.foo)) { // We won't get in this branch. But if we did, then `foo` is // now properly typed (and checked) as `string`. } } ```
@paul-marechal , |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've checked that we're finding the bug @eneufeld detected with this change.
Yes and no. While this PR might fix the issue you found, I still think it would be for the best to update the export namespace ProblemMarker {
export function is(node: unknown): node is ProblemMarker {
return Marker.is(node) && node.kind === PROBLEM_KIND;
}
} Just for good measure. edit: I pushed a commit that does that. |
b680ea8
to
e291789
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm happy with the changes 👍
aaab9ce
to
f1eda2a
Compare
f1eda2a
to
62c8992
Compare
The template parameter for `isObject` is currently used to force cast the value passed to the function, although there is no guarantee nor check done to ensure that this is really the case. This commit updates the typings so that the type passed to `isObject` is used to guide TypeScript during subsequent field type checking, assuming each field value is `unknown` and must also be type checked. Example: ```ts interface MyType { foo: string } const unknownValue: unknown = { foo: 2 }; if (isObject<MyType>(unknownValue)) { // We enter this branch because `unknownValue` is indeed an object, // and TypeScript now knows we might want to access the `foo` field // from our interface. But we can't yet assume to know the type of // `foo`, so it is still typed as `unknown` and we must check: if (isString(unknownValue.foo)) { // We won't get in this branch. But if we did, then `foo` is // now properly typed (and checked) as `string`. } } ```
The template parameter for
isObject
is currently used to force cast the value passed to the function, although there is no guarantee nor check done to ensure that this is really the case.This commit updates the typings so that the type passed to
isObject
is used to guide TypeScript during subsequent field type checking, assuming each field value isunknown
and must also be type checked.Example:
Fix #12253
Fix #12250
Close #12251
How to test
Should compile.
Review checklist
Reminder for reviewers