-
-
Notifications
You must be signed in to change notification settings - Fork 118
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
4.3.2 regression involving branded types #32
Comments
If you change the type of |
Thanks for the report! I had a quick look and it looks like type inverted = InvertPattern<{
fooBar: { type: 'foo' };
fooBarId: GuardPattern<BrandedId, BrandedId>;
}>;
// inverted: { fooBar: { type: 'foo' }; fooBarId: BrandedId }. This is correct
type t = ExtractPreciseValue<State, inverted>;
// t: never :(
// Here is the test case that should pass:
type cases = [
Expect<
Equal<
t,
{
fooBar: {
type: 'foo';
id: BrandedId;
value: string;
};
fooBarId: BrandedId;
}
>
>
]; Would you be interested in having a look at why this is a case and opening a PR if you find a way to fix it? It would be amazing to have more contributors than just myself on this project :) I would be happy to walk you through the code if you are interested and if you need some help |
I investigated a bit more on this issue and it looks like type BrandedId = string & { __brand: 'brandId' };
type BuiltInObjects =
| Function
| Error
| Date
| RegExp
| Generator
| { readonly [Symbol.toStringTag]: string };
export type IsPlainObject<o> = o extends object
? o extends BuiltInObjects
? false
: true
: false;
type x = IsPlainObject<BrandedId> // true in 4.4 and 4.3, false in 4.2 and 4.3-betas That's really odd, because the result of |
I think you might have already beat me to it, but thanks for the offer! I do want to look into the internals of ts-pattern if only to improve my type level programming, but also maybe to contribute a bit.
Yeah, if I had to guess from your investigation findings this is a typescript regression. We should probably open an issue or search for an existing issue on the typescript issue tracker. The fact that this was introduced sometime between 4.3-beta and 4.3.2 and its not reported as a breaking change makes me think this wasn't an intentional breaking change. Branded types/new type patterns do kinda feel like a second class citizen in typescript and a bit hacky, so its not too surprising that they might have missed it.
Yep, that fixes it, but I still think its best to raise this upstream. If you want I can try searching for a relevant issue to link here, or create a new one. |
@gvergnaud reported it here: microsoft/TypeScript#44353 |
I've been staring at the examples you provided, and I cannot help to conclude that it should be evaluating to If Am I going insane? |
No you are not! I think you are right, that was my conclusion too ;) That's why I ended up changing the code of ts-pattern rather than opening an issue on the TS repo. I think it's still a good thing that you opened this issue because it's better to let them know about this weird case and that it was broken in the previous versions. |
Maybe as a proper fix there should be some kind of guard for branded primitives. |
Describe the bug
I'm not sure if this is a typescript or a ts-pattern bug, but I thought you might be best placed to triage.
I tried upgrading to typescript 4.3 the other day, and I hit some odd type errors in ts-pattern usages. I've managed to narrow and simplify it down to this example which involves branded types:
4.4-dev playground (4.3-beta does not reproduce, and 4.3 isn't an option yet)
4.2 playground example
4.3-beta playground example
Versions
The text was updated successfully, but these errors were encountered: