-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
fix(types): Mark more methods bivariant #1029
Conversation
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit 32d7998:
|
@devanshj what's your call? |
Co-authored-by: Daishi Kato <dai-shi@users.noreply.github.com>
Here's a minimal version of what changed in 4.8: type Action<T> = (state: T) => T;
export type MakeBivariantMethod<T> = {
signature(arg: T | Partial<T> | Action<T>): void;
}['signature']
export interface StoreApi<T> {
prop: MakeBivariantMethod<T>;
}
type CheckExtendsStoreApi<T extends StoreApi<unknown>> = T;
type Test<T> = CheckExtendsStoreApi<StoreApi<T>>; // <- New correct error |
It seems to me that in export interface StoreApi<out T> {
getState: () => T
setState(state: T | Partial<T> | ((state: T) => T)): void
} But now in So now this fix (ie #1029) is a more correct one (I think @Andarist also reduced it to this but I wasn't sure then because #1008 was compiling). Although you don't need nor should you make - ((state: T) => T)
+ { _(state: T): T }["_"] I think in that case we don't even need downlevel-dts. I can make changes to #1004 or we can proceed with #1029 whatever @dai-shi prefers.
I'm not sure what "correct" means here. If by correct we mean mathematical correctness then we don't a way to measure correctness as bivariance is already mathematically incorrect (ie Also the change is a bit weird... interface F<out T> { // compiles
_(t: T): void
}
interface G<out T> { // compiles
_(t: (t: T) => T): void
}
interface H<out T> { // compiles
a(t: T): void
b(t: ((t: T) => T)): void
}
interface I<out T> { // does not compile
_(t: T | ((t: T) => T)): void
} I'd expect |
src/vanilla.ts
Outdated
export type SetState<T extends State> = { | ||
_( | ||
partial: T | Partial<T> | ((state: T) => T | Partial<T>), | ||
partial: T | Partial<T> | BivariantStateComputer<T>, | ||
replace?: boolean | undefined | ||
): void | ||
}['_'] | ||
type BivariantStateComputer<T> = { | ||
_(state: T): T | Partial<T> | ||
}['_'] |
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.
Let's inline BivariantStateComputer
.
export type SetState<T extends State> = { | |
_( | |
partial: T | Partial<T> | ((state: T) => T | Partial<T>), | |
partial: T | Partial<T> | BivariantStateComputer<T>, | |
replace?: boolean | undefined | |
): void | |
}['_'] | |
type BivariantStateComputer<T> = { | |
_(state: T): T | Partial<T> | |
}['_'] | |
export type SetState<T extends State> = { | |
_( | |
partial: T | Partial<T> | { _(state: T): T | Partial<T> }["_"], | |
replace?: boolean | undefined | |
): void | |
}['_'] |
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.
Yeah, inlining seems simple enough and more consistent.
Co-authored-by: Devansh Jethmalani <jethmalani.devansh@gmail.com>
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.
well, i'm not a ts wizard, but it looks good.
src/vanilla.ts
Outdated
export type SetState<T extends State> = { | ||
_( | ||
partial: T | Partial<T> | ((state: T) => T | Partial<T>), | ||
partial: T | Partial<T> | BivariantStateComputer<T>, | ||
replace?: boolean | undefined | ||
): void | ||
}['_'] | ||
type BivariantStateComputer<T> = { | ||
_(state: T): T | Partial<T> | ||
}['_'] |
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.
Yeah, inlining seems simple enough and more consistent.
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.
Thanks all for helping with types.
Fixes some upcoming build breaks in TypeScript 4.8. I'm not entirely sure the true root cause, but it looks like we're computing the correct variance of more of these types, leading to a (correct) error issued in covariant use sites like this: