Skip to content

Commit c5c1634

Browse files
authored
Internal TypeScript improvements (#2640)
* react/vue * wip * svelte * Update useForm.ts * Update InfiniteScroll.svelte * Update useForm.ts * Update useForm.ts
1 parent a59a7c5 commit c5c1634

File tree

18 files changed

+157
-126
lines changed

18 files changed

+157
-126
lines changed

packages/core/src/debug.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ export const stackTrace = (autolog = true) => {
22
try {
33
throw new Error()
44
} catch (e) {
5-
// @ts-ignore
6-
const stack = e.stack
5+
const stack = (e as Error).stack
76

87
if (!autolog) {
98
return stack

packages/react/src/Form.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ const Form = forwardRef<FormComponentRef, ComponentProps>(
7070
ref,
7171
) => {
7272
const form = useForm<Record<string, any>>({})
73-
const formElement = useRef<HTMLFormElement>(null)
73+
const formElement = useRef<HTMLFormElement>(undefined)
7474

7575
const resolvedMethod = useMemo(() => {
7676
return isUrlMethodPair(action) ? action.method : (method.toLowerCase() as Method)
@@ -96,13 +96,15 @@ const Form = forwardRef<FormComponentRef, ComponentProps>(
9696

9797
const formEvents: Array<keyof HTMLElementEventMap> = ['input', 'change', 'reset']
9898

99-
formEvents.forEach((e) => formElement.current.addEventListener(e, updateDirtyState))
99+
formEvents.forEach((e) => formElement.current!.addEventListener(e, updateDirtyState))
100100

101101
return () => formEvents.forEach((e) => formElement.current?.removeEventListener(e, updateDirtyState))
102102
}, [])
103103

104104
const reset = (...fields: string[]) => {
105-
resetFormFields(formElement.current, defaultData.current, fields)
105+
if (formElement.current) {
106+
resetFormFields(formElement.current, defaultData.current, fields)
107+
}
106108
}
107109

108110
const resetAndClearErrors = (...fields: string[]) => {

packages/react/src/InfiniteScroll.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,8 @@ const InfiniteScroll = forwardRef<InfiniteScrollRef, ComponentProps>(
181181

182182
// Elements
183183
getTriggerMargin: () => callbackPropsRef.current.buffer,
184-
getStartElement: () => resolvedStartElement,
185-
getEndElement: () => resolvedEndElement,
184+
getStartElement: () => resolvedStartElement!,
185+
getEndElement: () => resolvedEndElement!,
186186
getItemsElement: () => resolvedItemsElement,
187187
getScrollableParent: () => scrollableParent,
188188

packages/react/src/Link.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
router,
1010
shouldIntercept,
1111
shouldNavigate,
12+
VisitOptions,
1213
} from '@inertiajs/core'
1314
import { createElement, ElementType, forwardRef, useEffect, useMemo, useRef, useState } from 'react'
1415

@@ -59,7 +60,7 @@ const Link = forwardRef<unknown, InertiaLinkProps>(
5960
ref,
6061
) => {
6162
const [inFlightCount, setInFlightCount] = useState(0)
62-
const hoverTimeout = useRef<number>(null)
63+
const hoverTimeout = useRef<number>(undefined)
6364

6465
const _method = useMemo(() => {
6566
return isUrlMethodPair(href) ? href.method : (method.toLowerCase() as Method)
@@ -82,7 +83,7 @@ const Link = forwardRef<unknown, InertiaLinkProps>(
8283
const url = useMemo(() => mergeDataArray[0], [mergeDataArray])
8384
const _data = useMemo(() => mergeDataArray[1], [mergeDataArray])
8485

85-
const baseParams = useMemo(
86+
const baseParams = useMemo<VisitOptions>(
8687
() => ({
8788
data: _data,
8889
method: _method,
@@ -98,7 +99,7 @@ const Link = forwardRef<unknown, InertiaLinkProps>(
9899
[_data, _method, preserveScroll, preserveState, preserveUrl, replace, only, except, headers, async],
99100
)
100101

101-
const visitParams = useMemo(
102+
const visitParams = useMemo<VisitOptions>(
102103
() => ({
103104
...baseParams,
104105
onCancelToken,

packages/react/src/PageContext.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import { Page } from '@inertiajs/core'
12
import { createContext } from 'react'
23

3-
const pageContext = createContext(undefined)
4+
const pageContext = createContext<Page | null>(null)
45
pageContext.displayName = 'InertiaPageContext'
56

67
export default pageContext

packages/react/src/useForm.ts

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import {
22
CancelToken,
3+
Errors,
34
ErrorValue,
45
FormDataErrors,
56
FormDataKeys,
67
FormDataType,
78
FormDataValues,
89
Method,
910
Progress,
11+
RequestPayload,
1012
router,
1113
UrlMethodPair,
1214
VisitOptions,
@@ -27,6 +29,8 @@ export type SetDataAction<TForm extends Record<any, any>> = SetDataByObject<TFor
2729
SetDataByKeyValuePair<TForm>
2830

2931
type FormOptions = Omit<VisitOptions, 'data'>
32+
type SubmitArgs = [Method, string, FormOptions?] | [UrlMethodPair, FormOptions?]
33+
type TransformCallback<TForm> = (data: TForm) => object
3034

3135
export interface InertiaFormProps<TForm extends object> {
3236
data: TForm
@@ -38,7 +42,7 @@ export interface InertiaFormProps<TForm extends object> {
3842
wasSuccessful: boolean
3943
recentlySuccessful: boolean
4044
setData: SetDataAction<TForm>
41-
transform: (callback: (data: TForm) => object) => void
45+
transform: (callback: TransformCallback<TForm>) => void
4246
setDefaults(): void
4347
setDefaults<T extends FormDataKeys<TForm>>(field: T, value: FormDataValues<TForm, T>): void
4448
setDefaults(fields: Partial<TForm>): void
@@ -47,7 +51,7 @@ export interface InertiaFormProps<TForm extends object> {
4751
resetAndClearErrors<K extends FormDataKeys<TForm>>(...fields: K[]): void
4852
setError<K extends FormDataKeys<TForm>>(field: K, value: ErrorValue): void
4953
setError(errors: FormDataErrors<TForm>): void
50-
submit: (...args: [Method, string, FormOptions?] | [UrlMethodPair, FormOptions?]) => void
54+
submit: (...args: SubmitArgs) => void
5155
get: (url: string, options?: FormOptions) => void
5256
patch: (url: string, options?: FormOptions) => void
5357
post: (url: string, options?: FormOptions) => void
@@ -66,23 +70,23 @@ export default function useForm<TForm extends FormDataType<TForm>>(
6670
rememberKeyOrInitialValues?: string | TForm | (() => TForm),
6771
maybeInitialValues?: TForm | (() => TForm),
6872
): InertiaFormProps<TForm> {
69-
const isMounted = useRef(null)
73+
const isMounted = useRef(false)
7074
const rememberKey = typeof rememberKeyOrInitialValues === 'string' ? rememberKeyOrInitialValues : null
7175
const [defaults, setDefaults] = useState(
7276
(typeof rememberKeyOrInitialValues === 'string' ? maybeInitialValues : rememberKeyOrInitialValues) || ({} as TForm),
7377
)
7478
const cancelToken = useRef<CancelToken | null>(null)
75-
const recentlySuccessfulTimeoutId = useRef(null)
79+
const recentlySuccessfulTimeoutId = useRef<number>(undefined)
7680
const [data, setData] = rememberKey ? useRemember(defaults, `${rememberKey}:data`) : useState(defaults)
7781
const [errors, setErrors] = rememberKey
7882
? useRemember({} as FormDataErrors<TForm>, `${rememberKey}:errors`)
7983
: useState({} as FormDataErrors<TForm>)
8084
const [hasErrors, setHasErrors] = useState(false)
8185
const [processing, setProcessing] = useState(false)
82-
const [progress, setProgress] = useState(null)
86+
const [progress, setProgress] = useState<Progress | null>(null)
8387
const [wasSuccessful, setWasSuccessful] = useState(false)
8488
const [recentlySuccessful, setRecentlySuccessful] = useState(false)
85-
const transform = useRef((data) => data)
89+
const transform = useRef<TransformCallback<TForm>>((data) => data)
8690
const isDirty = useMemo(() => !isEqual(data, defaults), [data, defaults])
8791

8892
useEffect(() => {
@@ -97,16 +101,16 @@ export default function useForm<TForm extends FormDataType<TForm>>(
97101
const setDefaultsCalledInOnSuccess = useRef(false)
98102

99103
const submit = useCallback(
100-
(...args) => {
104+
(...args: SubmitArgs) => {
101105
const objectPassed = args[0] !== null && typeof args[0] === 'object'
102106

103-
const method = objectPassed ? args[0].method : args[0]
104-
const url = objectPassed ? args[0].url : args[1]
107+
const method = objectPassed ? args[0].method : (args[0] as Method)
108+
const url = objectPassed ? args[0].url : (args[1] as string)
105109
const options = (objectPassed ? args[1] : args[2]) ?? {}
106110

107111
setDefaultsCalledInOnSuccess.current = false
108112

109-
const _options = {
113+
const _options: VisitOptions = {
110114
...options,
111115
onCancelToken: (token) => {
112116
cancelToken.current = token
@@ -132,7 +136,7 @@ export default function useForm<TForm extends FormDataType<TForm>>(
132136
}
133137
},
134138
onProgress: (event) => {
135-
setProgress(event)
139+
setProgress(event || null)
136140

137141
if (options.onProgress) {
138142
return options.onProgress(event)
@@ -168,7 +172,7 @@ export default function useForm<TForm extends FormDataType<TForm>>(
168172
if (isMounted.current) {
169173
setProcessing(false)
170174
setProgress(null)
171-
setErrors(errors)
175+
setErrors(errors as FormDataErrors<TForm>)
172176
setHasErrors(true)
173177
}
174178

@@ -200,10 +204,12 @@ export default function useForm<TForm extends FormDataType<TForm>>(
200204
},
201205
}
202206

207+
const transformedData = transform.current(data) as RequestPayload
208+
203209
if (method === 'delete') {
204-
router.delete(url, { ..._options, data: transform.current(data) })
210+
router.delete(url, { ..._options, data: transformedData })
205211
} else {
206-
router[method](url, transform.current(data), _options)
212+
router[method](url, transformedData, _options)
207213
}
208214
},
209215
[data, setErrors, transform],
@@ -266,7 +272,7 @@ export default function useForm<TForm extends FormDataType<TForm>>(
266272
}, [dataAsDefaults])
267273

268274
const reset = useCallback(
269-
(...fields) => {
275+
(...fields: string[]) => {
270276
if (fields.length === 0) {
271277
setData(defaults)
272278
} else {
@@ -300,12 +306,12 @@ export default function useForm<TForm extends FormDataType<TForm>>(
300306
)
301307

302308
const clearErrors = useCallback(
303-
(...fields) => {
309+
(...fields: string[]) => {
304310
setErrors((errors) => {
305311
const newErrors = Object.keys(errors).reduce(
306312
(carry, field) => ({
307313
...carry,
308-
...(fields.length > 0 && !fields.includes(field) ? { [field]: errors[field] } : {}),
314+
...(fields.length > 0 && !fields.includes(field) ? { [field]: (errors as Errors)[field] } : {}),
309315
}),
310316
{},
311317
)
@@ -317,16 +323,18 @@ export default function useForm<TForm extends FormDataType<TForm>>(
317323
)
318324

319325
const resetAndClearErrors = useCallback(
320-
(...fields) => {
326+
(...fields: string[]) => {
321327
reset(...fields)
322328
clearErrors(...fields)
323329
},
324330
[reset, clearErrors],
325331
)
326332

327-
const createSubmitMethod = (method) => (url, options) => {
328-
submit(method, url, options)
329-
}
333+
const createSubmitMethod =
334+
(method: Method) =>
335+
(url: string, options: VisitOptions = {}) => {
336+
submit(method, url, options)
337+
}
330338
const getMethod = useCallback(createSubmitMethod('get'), [submit])
331339
const post = useCallback(createSubmitMethod('post'), [submit])
332340
const put = useCallback(createSubmitMethod('put'), [submit])
@@ -339,7 +347,7 @@ export default function useForm<TForm extends FormDataType<TForm>>(
339347
}
340348
}, [])
341349

342-
const transformFunction = useCallback((callback) => {
350+
const transformFunction = useCallback((callback: TransformCallback<TForm>) => {
343351
transform.current = callback
344352
}, [])
345353

packages/svelte/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
}
3636
},
3737
"scripts": {
38-
"build": "pnpm package && publint",
38+
"build": "pnpm package && svelte-check --tsconfig ./tsconfig.json && publint",
3939
"build:with-deps": "svelte-kit sync && vite build --config vite-with-deps.config.js",
4040
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
4141
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",

packages/svelte/src/components/Form.svelte

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
mergeDataIntoQueryString,
66
type Errors,
77
type FormComponentProps,
8+
type Method,
89
type FormDataConvertible,
910
type VisitOptions,
1011
isUrlMethodPair,
@@ -45,8 +46,8 @@
4546
let isDirty = false
4647
let defaultData: FormData = new FormData()
4748
48-
$: _method = isUrlMethodPair(action) ? action.method : (method.toLowerCase() as FormComponentProps['method'])
49-
$: _action = isUrlMethodPair(action) ? action.url : action
49+
$: _method = isUrlMethodPair(action) ? action.method : ((method ?? 'get').toLowerCase() as Method)
50+
$: _action = isUrlMethodPair(action) ? action.url : (action as string)
5051
5152
function getFormData(): FormData {
5253
return new FormData(formElement)
@@ -117,7 +118,7 @@
117118
...options,
118119
}
119120
120-
$form.transform(() => transform(_data)).submit(_method, url, submitOptions)
121+
$form.transform(() => transform!(_data)).submit(_method, url, submitOptions)
121122
}
122123
123124
function handleSubmit(event: Event) {

packages/svelte/src/components/InfiniteScroll.svelte

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
} from '@inertiajs/core'
1010
import { onDestroy, onMount } from 'svelte'
1111
12-
export let data: InfiniteScrollComponentBaseProps['data'] = undefined
12+
export let data: InfiniteScrollComponentBaseProps['data']
1313
export let buffer: InfiniteScrollComponentBaseProps['buffer'] = 0
1414
export let as: InfiniteScrollComponentBaseProps['as'] = 'div'
1515
export let manual: InfiniteScrollComponentBaseProps['manual'] = false
@@ -126,28 +126,28 @@
126126
127127
infiniteScrollInstance = useInfiniteScroll({
128128
// Data
129-
getPropName: () => data,
130-
inReverseMode: () => reverse,
129+
getPropName: () => data!,
130+
inReverseMode: () => reverse ?? false,
131131
shouldFetchNext: () => !onlyPrevious,
132132
shouldFetchPrevious: () => !onlyNext,
133-
shouldPreserveUrl: () => preserveUrl,
133+
shouldPreserveUrl: () => preserveUrl ?? false,
134134
135135
// Elements
136-
getTriggerMargin: () => buffer,
137-
getStartElement: () => resolvedStartElement,
138-
getEndElement: () => resolvedEndElement,
139-
getItemsElement: () => resolvedItemsElement,
136+
getTriggerMargin: () => buffer ?? 0,
137+
getStartElement: () => resolvedStartElement!,
138+
getEndElement: () => resolvedEndElement!,
139+
getItemsElement: () => resolvedItemsElement!,
140140
getScrollableParent: () => (resolvedItemsElement ? getScrollableParent(resolvedItemsElement) : null),
141141
142142
// Request callbacks
143143
onBeforePreviousRequest: () => (loadingPrevious = true),
144144
onBeforeNextRequest: () => (loadingNext = true),
145145
onCompletePreviousRequest: () => {
146-
requestCount = infiniteScrollInstance.dataManager.getRequestCount()
146+
requestCount = infiniteScrollInstance!.dataManager.getRequestCount()
147147
loadingPrevious = false
148148
},
149149
onCompleteNextRequest: () => {
150-
requestCount = infiniteScrollInstance.dataManager.getRequestCount()
150+
requestCount = infiniteScrollInstance!.dataManager.getRequestCount()
151151
loadingNext = false
152152
},
153153
})
@@ -167,7 +167,7 @@
167167
}
168168
}
169169
170-
$: manualMode = manual || (manualAfter > 0 && requestCount >= manualAfter)
170+
$: manualMode = manual || (manualAfter !== undefined && manualAfter > 0 && requestCount >= manualAfter)
171171
$: autoLoad = !manualMode
172172
173173
$: headerAutoMode = autoLoad && !onlyNext

packages/svelte/src/link.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ function link(
136136
return 30_000
137137
})()
138138

139-
cacheTags = cacheTagValues
139+
cacheTags = Array.isArray(cacheTagValues) ? cacheTagValues : [cacheTagValues]
140140

141141
method = isUrlMethodPair(params.href) ? params.href.method : (params.method?.toLowerCase() as Method) || 'get'
142142
;[href, data] = hrefAndData(method, params)

0 commit comments

Comments
 (0)