From 918fc4572e297854d01216c7a0310070860f8340 Mon Sep 17 00:00:00 2001 From: daishi Date: Tue, 19 Jul 2022 10:51:44 +0900 Subject: [PATCH] fix(types): use TS interfaces only for public api --- .eslintrc.json | 1 - src/react.ts | 30 ++++-------------------------- src/utils/derive.ts | 4 ++-- src/utils/devtools.ts | 4 ++-- src/utils/proxyWithComputed.ts | 30 ++++-------------------------- src/utils/watch.ts | 2 +- src/vanilla.ts | 27 +++++++++++++++------------ tests/derive.test.tsx | 2 +- 8 files changed, 29 insertions(+), 71 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 0e299b4d..e6238829 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -47,7 +47,6 @@ "@typescript-eslint/no-use-before-define": "off", "@typescript-eslint/no-empty-function": "off", "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/consistent-type-definitions": ["error", "interface"], "jest/consistent-test-it": [ "error", { "fn": "it", "withinDescribe": "it" } diff --git a/src/react.ts b/src/react.ts index 672b7ac1..d46b28f6 100644 --- a/src/react.ts +++ b/src/react.ts @@ -10,32 +10,10 @@ import { // The following is a workaround until ESM is supported. import useSyncExternalStoreExports from 'use-sync-external-store/shim' import { snapshot, subscribe } from './vanilla' -import type { INTERNAL_AsRef } from './vanilla' +import type { INTERNAL_Snapshot } from './vanilla' const { useSyncExternalStore } = useSyncExternalStoreExports -// Unfortunately, this doesn't work with tsc. -// Hope to find a solution to make this work. -// -// class SnapshotWrapper { -// fn(p: T) { -// return snapshot(p) -// } -// } -// type Snapshot = ReturnType['fn']> -// -// Using copy-paste types for now: -type AnyFunction = (...args: any[]) => any -type Snapshot = T extends AnyFunction - ? T - : T extends INTERNAL_AsRef - ? T - : T extends Promise - ? Snapshot - : { - readonly [K in keyof T]: Snapshot - } - const useAffectedDebugValue = ( state: object, affected: WeakMap @@ -47,7 +25,7 @@ const useAffectedDebugValue = ( useDebugValue(pathList.current) } -interface Options { +type Options = { sync?: boolean } @@ -126,9 +104,9 @@ interface Options { export function useSnapshot( proxyObject: T, options?: Options -): Snapshot { +): INTERNAL_Snapshot { const notifyInSync = options?.sync - const lastSnapshot = useRef>() + const lastSnapshot = useRef>() const lastAffected = useRef>() let inRender = true const currSnapshot = useSyncExternalStore( diff --git a/src/utils/derive.ts b/src/utils/derive.ts index 1f00c22c..4a05135a 100644 --- a/src/utils/derive.ts +++ b/src/utils/derive.ts @@ -2,7 +2,7 @@ import { getVersion, proxy, subscribe } from '../vanilla' type DeriveGet = (proxyObject: T) => T -interface Subscription { +type Subscription = { s: object // "s"ourceObject d: object // "d"erivedObject k: string // derived "k"ey @@ -198,7 +198,7 @@ export function derive( throw new Error('object property already defined') } const fn = derivedFns[key as keyof U] - interface DependencyEntry { + type DependencyEntry = { v: number // "v"ersion s?: Subscription // "s"ubscription } diff --git a/src/utils/devtools.ts b/src/utils/devtools.ts index 7d04f674..deaadb59 100644 --- a/src/utils/devtools.ts +++ b/src/utils/devtools.ts @@ -2,7 +2,7 @@ import { snapshot, subscribe } from '../vanilla' import type {} from '@redux-devtools/extension' // FIXME https://github.com/reduxjs/redux-devtools/issues/1097 -interface Message { +type Message = { type: string payload?: any state?: any @@ -10,7 +10,7 @@ interface Message { const DEVTOOLS = Symbol() -interface Options { +type Options = { enabled?: boolean name?: string } diff --git a/src/utils/proxyWithComputed.ts b/src/utils/proxyWithComputed.ts index 0bac708c..d46196f1 100644 --- a/src/utils/proxyWithComputed.ts +++ b/src/utils/proxyWithComputed.ts @@ -1,27 +1,5 @@ import { proxy, snapshot } from '../vanilla' -import type { INTERNAL_AsRef } from '../vanilla' - -// Unfortunately, this doesn't work with tsc. -// Hope to find a solution to make this work. -// -// class SnapshotWrapper { -// fn(p: T) { -// return snapshot(p) -// } -// } -// type Snapshot = ReturnType['fn']> -// -// Using copy-paste types for now: -type AnyFunction = (...args: any[]) => any -type Snapshot = T extends AnyFunction - ? T - : T extends INTERNAL_AsRef - ? T - : T extends Promise - ? Snapshot - : { - readonly [K in keyof T]: Snapshot - } +import type { INTERNAL_Snapshot } from '../vanilla' /** * proxyWithComputed @@ -51,9 +29,9 @@ export function proxyWithComputed( initialObject: T, computedFns: { [K in keyof U]: - | ((snap: Snapshot) => U[K]) + | ((snap: INTERNAL_Snapshot) => U[K]) | { - get: (snap: Snapshot) => U[K] + get: (snap: INTERNAL_Snapshot) => U[K] set?: (state: T, newValue: U[K]) => void } } @@ -66,7 +44,7 @@ export function proxyWithComputed( const { get, set } = ( typeof computedFn === 'function' ? { get: computedFn } : computedFn ) as { - get: (snap: Snapshot) => U[typeof key] + get: (snap: INTERNAL_Snapshot) => U[typeof key] set?: (state: T, newValue: U[typeof key]) => void } const desc: PropertyDescriptor = {} diff --git a/src/utils/watch.ts b/src/utils/watch.ts index 7c3602ab..14fbd635 100644 --- a/src/utils/watch.ts +++ b/src/utils/watch.ts @@ -3,7 +3,7 @@ import { subscribe } from '../vanilla' type Cleanup = () => void type WatchGet = (proxyObject: T) => T type WatchCallback = (get: WatchGet) => Cleanup | void | undefined -interface WatchOptions { +type WatchOptions = { sync?: boolean } diff --git a/src/vanilla.ts b/src/vanilla.ts index cf922daf..d898d16f 100644 --- a/src/vanilla.ts +++ b/src/vanilla.ts @@ -7,17 +7,13 @@ const HANDLER = __DEV__ ? Symbol('HANDLER') : Symbol() const PROMISE_RESULT = __DEV__ ? Symbol('PROMISE_RESULT') : Symbol() const PROMISE_ERROR = __DEV__ ? Symbol('PROMISE_ERROR') : Symbol() -/** - * This not a public API. - * It can be changed without notice. - */ -export interface INTERNAL_AsRef { +type AsRef = { $$valtioRef: true } const refSet = new WeakSet() -export function ref(o: T): T & INTERNAL_AsRef { +export function ref(o: T): T & AsRef { refSet.add(o) - return o as T & INTERNAL_AsRef + return o as T & AsRef } const isObject = (x: unknown): x is object => @@ -249,17 +245,24 @@ export function subscribe( } type AnyFunction = (...args: any[]) => any -type Snapshot = T extends AnyFunction + +/** + * This is not a public API. + * It can be changed without any notice. + */ +export type INTERNAL_Snapshot = T extends AnyFunction ? T - : T extends INTERNAL_AsRef + : T extends AsRef ? T : T extends Promise - ? Snapshot + ? INTERNAL_Snapshot : { - readonly [K in keyof T]: Snapshot + readonly [K in keyof T]: INTERNAL_Snapshot } -export function snapshot(proxyObject: T): Snapshot { +export function snapshot( + proxyObject: T +): INTERNAL_Snapshot { if (__DEV__ && !(proxyObject as any)?.[SNAPSHOT]) { console.warn('Please use proxy object') } diff --git a/tests/derive.test.tsx b/tests/derive.test.tsx index 174fdd5f..6cdafd68 100644 --- a/tests/derive.test.tsx +++ b/tests/derive.test.tsx @@ -411,7 +411,7 @@ describe('glitch free', () => { }) describe('two derived properties', () => { - interface State { + type State = { a: number derived1?: unknown derived2?: unknown