mirror of
https://github.com/pmndrs/zustand.git
synced 2025-12-08 19:45:52 +00:00
Rewrite TakeTwo, SkipTwo and Mutate to make them work for older ts versions too (#1348)
* create tsc v4.3.5 snapshot
* rewrite `TakeTwo` and `SkipTwo`
...to work with both pre 4.3.5 and post 4.3.5 subtyping rules.
The type `Test` in the following snippet resolves to `"yes"` for
<=4.3.5 but `"no"` for >4.3.5
```ts
type Test = [string, number?] extends [unknown] ? "yes" : "no"
```
(note 4.3.5 is bisected via typescript playground which skips
some versions so it might not be super accurate, but it's
accurate enough)
* fix lint
* fix pretest script to use tsc script instead of tsc bin
* revert tests
* add a workflow to test with old tsc
* fix typo
* oops, we need to run tsc
* test against build
* fix regex 🤦♂️
* oops, something was missing
* build in advance
* wip: more older versions
* wip: downgrade jest types
* minimum ts version 4.1.5
* minor fix
* make `Mutate` more complete
...wrt to the domain `StoreMutatorIdentifier[]` to help the type-checker
* fix lint
Co-authored-by: daishi <daishi@axlight.com>
This commit is contained in:
parent
ae4cc7f1b1
commit
93b5a43e82
2
.github/workflows/test-multiple-versions.yml
vendored
2
.github/workflows/test-multiple-versions.yml
vendored
@ -39,7 +39,7 @@ jobs:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '12'
|
||||
node-version: '14'
|
||||
cache: yarn
|
||||
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
|
||||
- run: yarn install --frozen-lockfile --check-files
|
||||
|
||||
43
.github/workflows/test-old-typescript.yml
vendored
Normal file
43
.github/workflows/test-old-typescript.yml
vendored
Normal file
@ -0,0 +1,43 @@
|
||||
name: Test Old TypeScript
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
|
||||
jobs:
|
||||
test_matrix:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
typescript:
|
||||
- 4.8.4
|
||||
- 4.7.4
|
||||
- 4.6.4
|
||||
- 4.5.5
|
||||
- 4.4.4
|
||||
- 4.3.5
|
||||
- 4.2.3
|
||||
- 4.1.5
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14'
|
||||
cache: yarn
|
||||
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
|
||||
- run: yarn install --frozen-lockfile --check-files
|
||||
- run: yarn build
|
||||
- name: Patch for Old TS
|
||||
run: |
|
||||
sed -i~ "s/\/\/ @ts-expect-error.*\[LATEST-TS-ONLY\]//" tests/*.tsx
|
||||
sed -i~ "s/\"exactOptionalPropertyTypes\": true,//" tsconfig.json
|
||||
sed -i~ "s/\"zustand\": \[\"\.\/src\/index\.ts\"\],/\"zustand\": [\".\/dist\/index.d.ts\"],/" tsconfig.json
|
||||
sed -i~ "s/\"zustand\/\*\": \[\"\.\/src\/\*\.ts\"\]/\"zustand\/*\": [\".\/dist\/*.d.ts\"]/" tsconfig.json
|
||||
sed -i~ "s/\"include\": .*/\"include\": [\"src\/types.d.ts\", \"dist\/**\/*\", \"tests\/**\/*\"],/" tsconfig.json
|
||||
- name: Test ${{ matrix.typescript }}
|
||||
run: |
|
||||
yarn add -D typescript@${{ matrix.typescript }}
|
||||
yarn tsc --noEmit
|
||||
@ -85,18 +85,19 @@ type Message = {
|
||||
state?: any
|
||||
}
|
||||
|
||||
type Cast<T, U> = T extends U ? T : U
|
||||
type Write<T, U> = Omit<T, keyof U> & U
|
||||
type TakeTwo<T> = T extends []
|
||||
type TakeTwo<T> = T extends { length: 0 }
|
||||
? [undefined, undefined]
|
||||
: T extends [unknown]
|
||||
? [...a0: T, a1: undefined]
|
||||
: T extends [unknown?]
|
||||
? [...a0: T, a1: undefined]
|
||||
: T extends [unknown, unknown]
|
||||
: T extends { length: 1 }
|
||||
? [...a0: Cast<T, unknown[]>, a1: undefined]
|
||||
: T extends { length: 0 | 1 }
|
||||
? [...a0: Cast<T, unknown[]>, a1: undefined]
|
||||
: T extends { length: 2 }
|
||||
? T
|
||||
: T extends [unknown, unknown?]
|
||||
: T extends { length: 1 | 2 }
|
||||
? T
|
||||
: T extends [unknown?, unknown?]
|
||||
: T extends { length: 0 | 1 | 2 }
|
||||
? T
|
||||
: T extends [infer A0, infer A1, ...unknown[]]
|
||||
? [A0, A1]
|
||||
|
||||
@ -18,11 +18,11 @@ declare module '../vanilla' {
|
||||
}
|
||||
|
||||
type Write<T, U> = Omit<T, keyof U> & U
|
||||
type SkipTwo<T> = T extends []
|
||||
type SkipTwo<T> = T extends { length: 0 }
|
||||
? []
|
||||
: T extends [unknown]
|
||||
: T extends { length: 1 }
|
||||
? []
|
||||
: T extends [unknown?]
|
||||
: T extends { length: 0 | 1 }
|
||||
? []
|
||||
: T extends [unknown, unknown, ...infer A]
|
||||
? A
|
||||
|
||||
@ -14,7 +14,9 @@ export interface StoreApi<T> {
|
||||
|
||||
type Get<T, K, F = never> = K extends keyof T ? T[K] : F
|
||||
|
||||
export type Mutate<S, Ms> = Ms extends []
|
||||
export type Mutate<S, Ms> = number extends Ms['length' & keyof Ms]
|
||||
? S
|
||||
: Ms extends []
|
||||
? S
|
||||
: Ms extends [[infer Mi, infer Ma], ...infer Mrs]
|
||||
? Mutate<StoreMutators<S, Ma>[Mi & StoreMutatorIdentifier], Mrs>
|
||||
|
||||
@ -106,9 +106,9 @@ it('should have correct (partial) types for setState', () => {
|
||||
|
||||
const store = create<Count>((set) => ({
|
||||
count: 0,
|
||||
// @ts-expect-error we shouldn't be able to set count to undefined
|
||||
// @ts-expect-error we shouldn't be able to set count to undefined [LATEST-TS-ONLY]
|
||||
a: () => set(() => ({ count: undefined })),
|
||||
// @ts-expect-error we shouldn't be able to set count to undefined
|
||||
// @ts-expect-error we shouldn't be able to set count to undefined [LATEST-TS-ONLY]
|
||||
b: () => set({ count: undefined }),
|
||||
c: () => set({ count: 1 }),
|
||||
}))
|
||||
@ -124,9 +124,9 @@ it('should have correct (partial) types for setState', () => {
|
||||
store.setState({})
|
||||
store.setState((previous) => previous)
|
||||
|
||||
// @ts-expect-error type undefined is not assignable to type number
|
||||
// @ts-expect-error type undefined is not assignable to type number [LATEST-TS-ONLY]
|
||||
store.setState({ count: undefined })
|
||||
// @ts-expect-error type undefined is not assignable to type number
|
||||
// @ts-expect-error type undefined is not assignable to type number [LATEST-TS-ONLY]
|
||||
store.setState((state) => ({ ...state, count: undefined }))
|
||||
})
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user