-
Notifications
You must be signed in to change notification settings - Fork 66
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
Get rid of tsd #436
Get rid of tsd #436
Conversation
function expectExact<T>() { | ||
return function<U extends T>( | ||
tValue: U | ||
): [T] extends [U] ? () => U : ["Argument of type", U, "does not match", T] { | ||
// @ts-expect-error Just for type checking | ||
return () => tValue; | ||
}; | ||
} | ||
|
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.
On the one hand, I was inclined to keep the expectType
name, but on the other, that would cause confusion for people familiar with tsd
. But we could go either way.
We could also break this into two functions, which might make it easier to spot that you accidentally omitted the trailing ()
:
function exact<T>() {
return function<U extends T>(
tValue: U
): [T] extends [U] ? () => U : [U, "does not match", T] {
// @ts-expect-error Just for type checking
return () => tValue;
};
}
function check<T>(fn: ()=>T): void {
fn();
}
And then call check(exact<T>()(arg))
.
In fact, this makes the error message work better. Now its:
Argument of type '[string, "does not match", string | number]' is not assignable to parameter of type '() => unknown'.
Type '[string, "does not match", string | number]' provides no match for the signature '(): unknown'.
This one is next after #430 |
Rebase and changelog, please. |
Updated. I'll just note one other way to do this that might be a bit clearer. Basically, instead of exactType()(x)(), we could use |
I don't have a strong opinion, so I'll defer to your taste. Feel free to send another PR if you decide you like another way better. |
Well, either trick is using heavily unstable features of TypeScript. I wouldn't recommend either approach for future rewrites, but for a small localized change to remove |
I checked it back to ts-3.3.3. Same behavior everywhere - so absent some statement of intent to change the behavior (perhaps you've seen something?) I think it's pretty stable. Its just currying; its hard to see how it could break without breaking huge amounts of typescript... |
Sorry, I didn't mean the problem is with currying. Problem is with conditional types, and, more precisely, them lacking any foundation in type theory. They might look like they're working, but even that equality check is incorrect. There're "better" type equalities in TS, but no single correct one. Unfortunately even type equality in TS is still an open problem. Mapped object types, conditional types, indexed types, type guards and, well, majority of TS's type system is unsound and inconsistent. It's best to avoid any of that if reliability is at stake. |
Get rid of
tsd
by rewritingexpectType
in a way that lets vanilla typescript check the types with the same precision.