-
-
Notifications
You must be signed in to change notification settings - Fork 244
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
Branded primitive types are incompatible with Snapshot<T> #747
Comments
Any type that extends Lines 31 to 37 in 5d0eca7
All branding/tagged/opaque types I've seen use an intersection with a faux property: // Some libraries use '__tag' or a Symbol instead of '__brand'
type Opaque<T, B> = T & { __brand: B } This passes the Since branded types are almost always used to wrap primitives, perhaps this could be worked around by special-casing primitive types? type Primitive = string | number | boolean | null | undefined | symbol | bigint
type Snapshot<T> = T extends SnapshotIgnore
? T
: T extends Promise<unknown>
? Awaited<T>
: T extends Primitive
? T
: T extends object
? { readonly [K in keyof T]: Snapshot<T[K]> }
: T |
Thanks for reporting. |
Unfortunately that doesn't work with all type branding solutions. For one, the declare const tag: unique symbol; // not exported!
type Tagged<Token> = { readonly [tag]: Token }; // not exported!
export type Opaque<Type, Token> = Type & Tagged<Token>; So directly targeting |
Do we have an ultimate solution? I thought we could only cover some typical cases. The last resort would be module augmentation, maybe. |
I think we just let people do |
Adding primitive types to type PrimitiveType = string | number | boolean | null | undefined | symbol | bigint;
type SnapshotIgnore = /* everything else */ | PrimitiveType; |
Ah, I see what you mean now. Would you like to open a PR? |
Sure |
Summary
Branded/tagged types are often used to achieve nominal typing. (1, 2) Several libraries (e.g. type-fest, ts-essentials) offer utility types such as
Opaque<T>
to support this.Unfortunately, the
Snapshot<T>
type in Valtio does not play nice with branded types. Specifically, a branded type becomes broken when passed throughSnapshot<T>
:Link to reproduction
https://www.typescriptlang.org/play?#code/C4TwDgpgBAQgTgQwHYBMA8AVANLAfFAXigygDIoBvKAfWoCNFUAuWKAXwChRIoBVAZwhwAkikKxG6fsDgBLJAHMcAcgFDRy3By7hoauOIocoJqLJQt9ojpx099AZSQIw-ABYB7YOKcv3XtH0tAHpg0wA9AH5tUNgIABsPAHczfigAYw8wWQgxADM4DwBbJg5Yt2BgVyZQhVlgNwBXOgA6TKLgsCLUOH5ggDcEeOBZD2C6RLpggFYUAAYIdIQAdlz0gCZphBW8gEZlvLoADjmj9Yg9gBZ1y8uEAGZpvPTd9bp14P44dIHkWXj4ggWsB+NpuNAAIJIEAAMUaSHSIw8SHEAAoWhiEHAFPwWMgQABtAC6AEpCPh8WDdFAIfwAEoXQxQAAkzMGw1GDLyLBkjWgtnBUF8rk8wGECiQHjg0AIxigAB8oAARBDACByxUAWRcaHxOHxWhMiocEGAuuhhoVUAA6hAEABrbVgc0gfUWjU2u32k1mg0e2lcj0AUTghTgHoZCiDAA8wP7oXCEUikFSeML-GaMPgiCQING1ag0unReLJdK5ZFiHKWLn8xBC1AAAqFIqyQRoeH2yVJJCWysQpIIeq5TCWmtQPMFlBpDx0ABWi2AFcoUGlCBQyPiICgBIA0mYUfaICAPHliESWMWAhg90T8JwTDWgA
Check List
Please do not ask questions in issues.
Please include a minimal reproduction.
The text was updated successfully, but these errors were encountered: