You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Inconsistent Behavior with Equality Check Using Pick<Readonly<T>, K> in Mapped TypeΒ #58163
interfaceO{foo: string;}typeEqual<X,Y>=(<T>()=>TextendsX ? 1 : 2)extends<T>()=>TextendsY ? 1 : 2 ? true : false;typeJustPick<T>={[KinkeyofT]: Pick<T,K>;};typetest_0=JustPick<O>["foo"];// ^?: { foo: string }typePickReadonly<T>={[KinkeyofT]: Pick<Readonly<T>,K>;};typetest_1=PickReadonly<O>["foo"];// ^?: { readonly foo: string }typetest_2=Equal<{foo: string},{readonlyfoo: string}>;// ^?: falsetypeStrange<T>={[KinkeyofT]: Equal<Pick<T,K>,Pick<Readonly<T>,K>>;// ^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^ This should be { readonly foo: string } according to `PickReadonly`// ^^^^^^^^^^// This should be { foo: string } according to `JustPick`// ... so `Equal<Pick<T, K>, Pick<Readonly<T>, K>>` should be `false` according to `test_2`}typetest_3=Strange<O>["foo"];// ^?: true <- Why?typetest_4=Equal<Pick<O,"foo">,Pick<Readonly<O>,"foo">>;// ^?: false
π Actual behavior
Type of test_3 is true instead of expected false like test_2 and test_4.
π Expected behavior
Type of test_3 should be false like test_2 and test_4.
This definition of Equal intentionally does the one thing that relies on the internal representation of types in the compiler. I really do not recommend using it. A definition that isn't reverse-engineered to actively rely on implementation details is
typeEqual<X,Y>=[X,Y]extends[Y,X] ? true : false;
which gives consistent results
readonly doesn't affect assignability so can't really be used in conditional types like this. Attempts to manifest other behavior will ultimately fail.
This definition of Equal intentionally does the one thing that relies on the internal representation of types in the compiler. I really do not recommend using it. A definition that isn't reverse-engineered to actively rely on implementation details is
typeEqual<X,Y>=[X,Y]extends[Y,X] ? true : false;
which gives consistent results
readonly doesn't affect assignability so can't really be used in conditional types like this. Attempts to manifest other behavior will ultimately fail.
Thanks for the detailed responseβit really cleared things up for me! I appreciate your help and the alternative you provided.
Activity
RyanCavanaugh commentedon Apr 12, 2024
This definition of
Equalintentionally does the one thing that relies on the internal representation of types in the compiler. I really do not recommend using it. A definition that isn't reverse-engineered to actively rely on implementation details iswhich gives consistent results
readonlydoesn't affect assignability so can't really be used in conditional types like this. Attempts to manifest other behavior will ultimately fail.Snowflyt commentedon Apr 13, 2024
Thanks for the detailed responseβit really cleared things up for me! I appreciate your help and the alternative you provided.