react-native-gesture-handler
Version:
Declarative API exposing native platform touch and gesture system to React Native
60 lines (55 loc) • 2.81 kB
text/typescript
export type SharedValue<Value = unknown> = {
value: Value;
get(): Value;
set(value: Value | ((value: Value) => Value)): void;
addListener: (listenerID: number, listener: (value: Value) => void) => void;
removeListener: (listenerID: number) => void;
modify: (
modifier?: <T extends Value>(value: T) => T,
forceUpdate?: boolean
) => void;
};
// Utility type that turns `T` into `T | SharedValue<T>`. `P` is used to avoid splitting union types.
export type SharedValueOrT<T, P = never> =
// We always want to get `T` in the resulting type.
| T
// If `T` is one of the types in `P`, we don't want to split the union, so we return SharedValue<T>.
| (Exclude<T, undefined> extends P
? SharedValue<Exclude<T, undefined>>
: // If `T` is not in `P`, we want to split the union and wrap each member with SharedValue, using Distributive Conditional Types (https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#distributive-conditional-types).
T extends any
? // Wrap each member of the union with SharedValue.
SharedValue<Exclude<T, undefined>>
: // If `T` is only one type, just return SharedValue<T>.
SharedValue<Exclude<T, undefined>>);
// Utility type that decides whether to recurse for objects or apply SharedValue directly.
export type WithSharedValue<T, P = never> = T extends object
? WithSharedValueRecursive<T, P>
: Simplify<SharedValueOrT<T, P>>;
// Apply SharedValue recursively. P is used to make sure that composed types won't be expanded.
// For example, if we pass `HoverEffect` as P, then resulting type will have HoverEffect | SharedValue<HoverEffect>,
// not HoverEffect, SharedValue<HoverEffect.NONE>, ...
type WithSharedValueRecursive<T extends object, P> = {
[K in keyof T]: Exclude<T[K], undefined> extends P
? Simplify<SharedValueOrT<T[K], P>>
: // Special case for boolean as passing `boolean` as P doesn't look ok.
boolean extends T[K]
? boolean | SharedValue<boolean> | Extract<T[K], undefined>
: // Special handling for tuples [number, number].
T[K] extends [number, number]
? [WithSharedValue<number, P>, WithSharedValue<number, P>]
: // Default case: apply the MaybeWithSharedValue logic recursively or as a direct SharedValue wrap.
WithSharedValue<T[K], P>;
};
// Simplifies types for end users.
// For example, changes SharedValueOrT<number> into number | SharedValue<number>.
type Simplify<T> =
T extends SharedValue<never>
? never
: // eslint-disable-next-line @typescript-eslint/no-explicit-any
T extends SharedValue<any>
? T
: {
// For a generic object, retain the original structure while forcing an object type
[K in keyof T]: T[K];
} & NonNullable<unknown>;