Skip to content

Commit e8fe471

Browse files
authored
Merge pull request #398 from Kovensky/more-typescript
More TypeScript updates
2 parents 2e44144 + e622f17 commit e8fe471

File tree

2 files changed

+76
-10
lines changed

2 files changed

+76
-10
lines changed

types/hooks.d.ts

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { CSSProperties, RefObject } from 'react'
12
import {
23
SpringConfig,
34
SpringBaseProps,
@@ -6,6 +7,10 @@ import {
67
} from './universal'
78
export { SpringConfig, SpringBaseProps, TransitionKeyProps, State }
89

10+
export { config, interpolate } from './universal'
11+
// hooks are currently web-only
12+
export { animated } from './web'
13+
914
/** List from `function getForwardProps` in `src/shared/helpers` */
1015
type ExcludedProps =
1116
| 'to'
@@ -43,18 +48,34 @@ export type SetUpdateFn<DS extends object> = (ds: DS) => void
4348

4449
// The hooks do emulate React's 'ref' by accepting { ref?: React.RefObject<Controller> } and
4550
// updating it. However, there are no types for Controller, and I assume it is intentionally so.
51+
// This is a partial interface for Controller that has only the properties needed for useChain to work.
52+
export interface ReactSpringHook {
53+
start(): void
54+
stop(): void
55+
}
56+
57+
export function useChain(refs: ReadonlyArray<RefObject<ReactSpringHook>>): void
58+
// this looks like it can just be a single overload, but we don't want to allow
59+
// timeFrame to be specifiable when timeSteps is explicitly "undefined"
60+
export function useChain(
61+
refs: ReadonlyArray<RefObject<ReactSpringHook>>,
62+
timeSteps: number[],
63+
timeFrame?: number
64+
): void
65+
4666
export interface HooksBaseProps
4767
extends Pick<SpringBaseProps, Exclude<keyof SpringBaseProps, 'config'>> {
4868
// there is an undocumented onKeyframesHalt which passes the controller instance,
4969
// so it also cannot be typed unless Controller types are written
70+
ref?: React.RefObject<ReactSpringHook>
5071
}
5172

5273
export interface UseSpringBaseProps extends HooksBaseProps {
5374
config?: SpringBaseProps['config']
5475
}
5576

56-
export type UseSpringProps<DS extends UseSpringBaseProps> = Merge<
57-
DS,
77+
export type UseSpringProps<DS extends object> = Merge<
78+
DS & UseSpringBaseProps,
5879
{
5980
from?: InferFrom<DS>
6081
/**
@@ -65,6 +86,12 @@ export type UseSpringProps<DS extends UseSpringBaseProps> = Merge<
6586
>
6687

6788
// there's a third value in the tuple but it's not public API (?)
89+
export function useSpring<DS extends CSSProperties>(
90+
values: UseSpringProps<DS & CSSProperties>
91+
): ForwardedProps<DS>
92+
export function useSpring<DS extends CSSProperties>(
93+
getProps: () => UseSpringProps<DS & CSSProperties>
94+
): [ForwardedProps<DS>, SetUpdateFn<DS>]
6895
export function useSpring<DS extends object>(
6996
getProps: () => UseSpringProps<DS>
7097
): [ForwardedProps<DS>, SetUpdateFn<DS>]
@@ -73,6 +100,14 @@ export function useSpring<DS extends object>(
73100
): ForwardedProps<DS>
74101

75102
// there's a third value in the tuple but it's not public API (?)
103+
export function useTrail<DS extends CSSProperties>(
104+
count: number,
105+
getProps: () => UseSpringProps<DS & CSSProperties>
106+
): [ForwardedProps<DS>[], SetUpdateFn<DS>]
107+
export function useTrail<DS extends CSSProperties>(
108+
count: number,
109+
values: UseSpringProps<DS & CSSProperties>
110+
): ForwardedProps<DS>[] // safe to modify (result of .map)
76111
export function useTrail<DS extends object>(
77112
count: number,
78113
getProps: () => UseSpringProps<DS>
@@ -132,6 +167,9 @@ export interface UseTransitionResult<TItem, DS extends object> {
132167
props: ForwardedProps<DS>
133168
}
134169

170+
export function useTransition<TItem, DS extends CSSProperties>(
171+
values: Merge<DS & CSSProperties, UseTransitionProps<TItem, DS>>
172+
): UseTransitionResult<TItem, ForwardedProps<DS>>[] // result array is safe to modify
135173
export function useTransition<TItem, DS extends object>(
136174
values: Merge<DS, UseTransitionProps<TItem, DS>>
137175
): UseTransitionResult<TItem, ForwardedProps<DS>>[] // result array is safe to modify
@@ -179,30 +217,63 @@ export namespace useKeyframes {
179217

180218
// fun fact: the state is literally named "undefined" if you're using this overload
181219
// the docs are vague but it seems this just loops the one animation forever?
220+
export function spring<DS extends CSSProperties>(
221+
animation:
222+
| ReadonlyArray<DS & CSSProperties>
223+
| ReadonlyArray<KeyframeFn<DS & CSSProperties>>
224+
| KeyframeFn<DS & CSSProperties>,
225+
initialProps?: UseSpringProps<DS & CSSProperties>
226+
): UseSpringKeyframes<DS & CSSProperties>
182227
export function spring<DS extends object>(
183228
animation:
184229
| ReadonlyArray<DS>
185230
| ReadonlyArray<KeyframeFn<DS>>
186231
| KeyframeFn<DS>,
187232
initialProps?: UseSpringProps<DS>
188233
): UseSpringKeyframes<DS>
234+
// this overload does provide CSSProperties autocompletes, but only as long as config, delay, onRest
235+
// et al are not specified. It's not possible to say TSlotNames can be
236+
// "string but not keyof SpringKeyframeSlotsConfig".
237+
export function spring<
238+
TSlotNames extends string,
239+
TSlots extends Record<TSlotNames, CSSProperties>
240+
>(
241+
slots: TSlots &
242+
Record<TSlotNames, CSSProperties> &
243+
SpringKeyframeSlotsConfig,
244+
initialProps?: UseSpringProps<CSSProperties>
245+
): UseSpringKeyframesWithSlots<TSlots>
189246
// unfortunately, it's not possible to infer the type of the callback functions (if any are given)
190-
// while also remaining possible to infer the slot names. Callback functions have to be cast with
247+
// while also remaining possible to infer the slot contents. Callback functions have to be cast with
191248
// `as useKeyframes.KeyframeFn<{ ... }>`.
192249
// it's also not possible to specify the types of the values inside TSlots. This is a mess.
193-
export function spring<TSlots extends object>(
250+
export function spring<
251+
TSlotNames extends string,
252+
TSlots extends Record<TSlotNames, any>
253+
>(
194254
slots: TSlots & SpringKeyframeSlotsConfig,
195255
// also unfortunately not possible to strongly type this either
196256
initialProps?: UseSpringProps<any>
197257
): UseSpringKeyframesWithSlots<TSlots>
198258

259+
export function trail<DS extends CSSProperties>(
260+
animation:
261+
| ReadonlyArray<DS & CSSProperties>
262+
| ReadonlyArray<KeyframeFn<DS & CSSProperties>>
263+
| KeyframeFn<DS & CSSProperties>,
264+
initialProps?: UseSpringProps<DS>
265+
): UseTrailKeyframes<DS>
199266
export function trail<DS extends object>(
200267
animation:
201268
| ReadonlyArray<DS>
202269
| ReadonlyArray<KeyframeFn<DS>>
203270
| KeyframeFn<DS>,
204271
initialProps?: UseSpringProps<DS>
205272
): UseTrailKeyframes<DS>
273+
// we unfortunately can't use the same trick in trail as we did in spring to have autocomplete for
274+
// CSS properties, for the same reason the spring trick stops working when a config key is given.
275+
// It would fail as soon as `items`, a required property, is specified, as its value
276+
// (necessarily an array-like) would not be compatible with CSSProperties.
206277
export function trail<TItem, TSlots extends object>(
207278
slots: TSlots & TrailKeyframeSlotsConfig<TItem>,
208279
initialProps?: UseSpringProps<any>

types/universal.d.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export interface SpringBaseProps {
6464
onStart?(): void
6565
}
6666

67-
export interface SpringProps<DS extends object = {}> {
67+
export interface SpringProps<DS extends object = {}> extends SpringBaseProps {
6868
/**
6969
* Base styles
7070
* @default {}
@@ -87,11 +87,6 @@ export interface SpringProps<DS extends object = {}> {
8787
* Takes a function that receives interpolated styles
8888
*/
8989
children?: SpringRendererFunc<DS>
90-
/**
91-
* Prevents animation if true, you can also pass individual keys
92-
* @default false
93-
*/
94-
immediate?: boolean | string[] | ((key: string) => boolean)
9590
/**
9691
* Inject props
9792
* @default undefined

0 commit comments

Comments
 (0)