-
Notifications
You must be signed in to change notification settings - Fork 8
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
idea: .branded.inspect
to view deep prop types
#113
base: main
Are you sure you want to change the base?
Conversation
commit:
|
: Not<IsNever<NominalType<T, Options>>> extends true | ||
? {type: NominalType<T, Options>} |
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 sure there's a better way to do this without having to explicitly check for never/user NominalType
twice
@@ -47,7 +47,7 @@ export type MismatchInfo<Actual, Expected> = | |||
K extends keyof Expected ? Expected[K] : never | |||
> | |||
} | |||
: StrictEqualUsingBranding<Actual, Expected> extends true | |||
: StrictEqualUsingBranding<Actual, Expected, DeepBrandOptionsDefaults> extends true |
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.
this is temp - we should make sure we respect whatever options the .branded
that's calling this has mebe??
export type ExpectNullable<T> = {[expectNullable]: T; result: Not<StrictEqualUsingBranding<T, NonNullable<T>>>} | ||
export type ExpectNullable<T> = { | ||
[expectNullable]: T | ||
result: Not<StrictEqualUsingBranding<T, NonNullable<T>, DeepBrandOptionsDefaults>> |
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.
this is temp - we should make sure we respect whatever options the .branded
that's calling this has mebe?? or should this not be using branding at all?
probably branding should always be opt-in since it can be slow
.inspect
to view deep prop types.branded.inspect
to view deep prop types
Seems like this would have very niche use cases. What's the difference between: expectTypeOf(bad).returns.branded.inspect({
foundProps: {
'.meta.parsed': 'any',
},
}) and this: expectTypeOf(bad)
.returns.toHaveProperty('meta')
.toHaveProperty('parsed')
.toBeAny() |
It's basically DX. The toHaveProperty one is useful when you deliberately made meta.parsed any. The .branded.inspect one is useful if you have a big complex object and you want to make sure that there are no anys hiding in it - you don't know it's So basically I think I'd only check anything in when foundProps is empty. But when something goes wrong, it'll find where the bad types are hiding. |
@mmkal That actually makes a lot of sense. I think an explanation similar to that should probably be included in the docs. Something like |
Use
.branded.inspect
to find badly-defined paths:This finds
any
andnever
types deep within objects. This can be useful for debugging, since you will get autocomplete for the bad paths, but is a fairly heavy operation, so use with caution for large/complex types.PR notes: this also adds a
nominalTypes
option toDeepBrand
. Reason being, a type likeDate
which has tons of methods can blow up the size of the type, and hurt performance/make us more likely to hit the dreaded "type instantiation is excessively deep" error. So now, by default DeepBrand is passednominalTypes: {Date: Date}
which basically means if it sees a type matchingDate
(usingMutuallyExtends
), it will just put{type: 'Date'}
in that spot in the big branded schema thing, and stop recursing.In theory people could configure this so they could do:
Which should improve performance and reliability.
But mostly I just added it to make sure
Date
didn't break the newinspect
functionality. Probably needs more careful thinking.This could go in post-v1 since it's non-breaking.