Repository navigation
Generics in conditionals have differing behavior in 4.8 #49490
Description
I found a break in zustand from looking at the logs of a failed NewErrors run. It might be more correct, but figured it was worth noting.
export type Store<T extends object> = {
setState: (x: T) => void
getState: () => T;
}
type ExtractState<S> = S extends { getState: () => infer T } ? T : never
type Extractable<S extends Store<object>> = {
getServerState?: () => ExtractState<S>
}
export function f<TState extends object>(api: Extractable<Store<TState>>) {
// ~~~~~~~~~~~~~
// Type 'Store<TState>' does not satisfy the constraint 'Store<object>'.
// Types of property 'setState' are incompatible.
// Type '(x: TState) => void' is not assignable to type '(x: object) => void'.
// Types of parameters 'x' and 'x' are incompatible.
// Type 'object' is not assignable to type 'TState'.
// 'object' is assignable to the constraint of type 'TState', but 'TState' could be instantiated with a different subtype of constraint 'object'.
}https://github.com/pmndrs/zustand/blob/197e5d41993b0e3ad6ebef9a7e6a9161753072f1/src/react.ts#L30
export function useStore<TState extends State, StateSlice>(
api: WithReact<StoreApi<TState>>,
// ~~~~~~~~~~~~~~~~
// error TS2344: Type 'StoreApi<TState>' does not satisfy the constraint 'StoreApi<object>'.There's a few of these.
New errors for non-composite project https://github.com/pmndrs/zustand/blob/197e5d41993b0e3ad6ebef9a7e6a9161753072f1/tsconfig.json
-
TS2344 at https://github.com/pmndrs/zustand/blob/197e5d41993b0e3ad6ebef9a7e6a9161753072f1/src/react.ts#L30
error TS2344: Type 'StoreApi<TState>' does not satisfy the constraint 'StoreApi<object>'. -
TS2344 at https://github.com/pmndrs/zustand/blob/197e5d41993b0e3ad6ebef9a7e6a9161753072f1/src/react.ts#L56
error TS2344: Type 'Mutate<StoreApi<T>, Mos>' does not satisfy the constraint 'WithReact<StoreApi<object>>'. -
TS2344 at https://github.com/pmndrs/zustand/blob/197e5d41993b0e3ad6ebef9a7e6a9161753072f1/src/react.ts#L59
error TS2344: Type 'Mutate<StoreApi<T>, Mos>' does not satisfy the constraint 'WithReact<StoreApi<object>>'. -
TS2345 at https://github.com/pmndrs/zustand/blob/197e5d41993b0e3ad6ebef9a7e6a9161753072f1/src/react.ts#L68
error TS2345: Argument of type 'StoreApi<T>' is not assignable to parameter of type 'WithReact<StoreApi<object>>'. -
error TS2344: Type 'StoreApi<CounterState>' does not satisfy the constraint 'StoreApi<object>'. -
error TS2344: Type 'StoreApi<CounterState>' does not satisfy the constraint 'StoreApi<object>'. -
error TS2344: Type 'StoreApi<CounterState>' does not satisfy the constraint 'StoreApi<object>'. -
error TS2344: Type 'StoreApi<CounterState>' does not satisfy the constraint 'StoreApi<object>'. -
error TS2322: Type 'StoreApi<Omit<{ count: number; }, never>>' is not assignable to type 'StoreApi<object>'. -
error TS2344: Type 'StoreApi<ExampleState>' does not satisfy the constraint 'WithReact<StoreApi<object>>'.
Originally posted by Daniel Rosenwasser (@DanielRosenwasser) in #49488 (comment)
Activity
yume-chan commentedon Jun 12, 2022
TypeScript 4.7 is producing the same error.
https://www.typescriptlang.org/play?ts=4.7.2#code/KYDwDg9gTgLgBDAnmYcDKNrADwBU6gzAB2AJgM5wQBGAVsAMYwB8cAvHAN4BQcfc5YDAwBDIgC44AChCTcASnasAbhACWpXvwDmQ0ROmK2rXAG5uAX27ckKOAFEQMKCKb6caVhzQEnJClxwusIwYsCSUkasasQAZsBQcPgWcAD8SXCSxMDKCda2qI7OrqHUADYevkRklBhY2DT0TMxeXFp8wWgJuVDuqRFRDk4ubqFE2J6W1qCQsHCxAK7ETGoQxPN47lX+lI2MLFIiYGqSRSOlFROYUDi47i2KnBZAA
And I remember hitting it very frequently in my own project, which requires me to write
type Extractable<S extends Store<any>>instead.Andarist commentedon Jun 12, 2022
cc Devansh Jethmalani (@devanshj) - you might find this interesting
devanshj commentedon Jun 13, 2022
Thanks for the ping Mateusz Burzyński (@Andarist)!
Will take a look into it soon but for the time being I want to point out that Daniel Rosenwasser (@DanielRosenwasser)'s reproduction is incorrect because zustands's
StorehassetState'sTbivaraint, makingTinStore<T>covariant...And this compiles in both 4.7 and 4.8. So the errors being reported (which I haven't looked into yet) seem to be caused by some other reason.
devanshj commentedon Jun 13, 2022
From pmndrs/zustand#1004
DanielRosenwasser commentedon Jun 13, 2022
Hm, not sure how I made that slip-up, and I'm honestly a little confused about the interface/type alias difference. If you have some time to get a minimal repro that'd be at the very least useful for us to investigate.
Andarist commentedon Jun 13, 2022
This is quite complex and beyond my understanding. We can already observe the issue with
typehere. However, the same behavior can be observed on 4.7 with this and if we changetypeto aninterfacethen we might see an error on the variance annotation, see here.In Zustand repo I couldn't see the same annotation error though so I kept digging... and I've somewhat narrowed it down to this. In here we won't observe the variance annotation error but it's quite easy to get it - by removing some seamingly unrelated lines of code.
The code here has some cycles and stuff and I think that this just makes variance measurement to give up and thus it ends up too forgiving. For some reason though the type-based variant was accepted in the past and now it isn't. It looks a little bit like as if variance computation became slightly smarter now and errors sooner rather than reporting unmeasurable (or similar)
Note that I'm just guessing a lot here.
devanshj commentedon Jun 14, 2022
Yeah I too am not sure what's up with the interface vs type alias thing. Will try to get a minimal repro if I find time for it.
jcalz commentedon Jun 16, 2024
This SO question is running into this.
FelixZY commentedon Jun 16, 2024
I see there has been some requests for a minimal reproduction. I think the code used in my SO question (linked by Joe Calzaretta (@jcalz) ) might be able to provide that:
Here's a playground link which includes objects proving that the
WorkOrdertype is working as expected despite the error: https://www.typescriptlang.org/play/?ts=5.4.5#code/JYOwLgpgTgZghgYwgAgGoQBbAQGxQbwF8AoUSWRFAQWCgAcc4QUIAPSEAEwGc1Ns8yfMWTIQAVwC2AI2gAuMVNlQA3MRJlo8JMgBCAezhhkbDjz5ZcBEcgT6c+qAu5gooAOZqN4LZWQB1RwBrbgx9OgAeABV0S0FTCC5eWIEUAF4LVIA+IRsAN34rKIBPOggFGMK8NVEoCDo4WgUACgK48uRK9oBKZDScwKgggHkoTmgIsCxuLK9SHwodQZGxiajl0PCTdkTzDbDI9eDNugBtACI21JKy84BdLJzhUSurCv3wi9e8G4h7ueIdhALmQjnGUCoCmWo3BEQ+kRo9EYzEefVyLyqHWeokUMnkyAAjAAmADMABobIQKYQ1ID9MDjGDoLoocEYRN4REDEZURlsd8sTZRHYHE5kOdpDhxH8KaIqepaUCQUyoABhVlDdlQOHHA4RREMJgQXno5AChTY4X2RwKCVSmXIAD0juQAFEAEru4bugCEyGG0gAVhAEMYcMByHAcMhJHBiqCQDh49wyghgDB40EQPoAO4gZB0KDhaBgYAQbhk5BMTjIADkIscteQnH05bE+mMbGAINAyDApRQtYNyIgtcp1JUQAIndeed, with TS 4.7 there are no (unexpected) errors but in 4.8 there is.
Andarist commentedon Jun 17, 2024
The one above bisects to 4.8.0-dev.20220528 and more specifically to removing those lines:
https://github.com/microsoft/TypeScript/pull/49119/files#diff-d9ab6589e714c71e657f601cf30ff51dfc607fc98419bf72e04f6b0fa92cc4b8L19578-L19584