在调用 React useState 的回调中使用 Typescript 泛型 setter
Using Typescript generics in a callback invoking a React useState setter
根据 Typescript,此代码存在以下问题:Argument of type 'number' is not assignable to parameter of type 'SetStateAction<T>'.ts(2345)
。
用类型或类型联合代替泛型的类似版本会起作用(事实上,可能会推荐具有所有预期类型的联合)。
不过,如果我想坚持使用泛型,我将如何修改此代码以使其被接受?
import React, { Dispatch, SetStateAction, useState } from 'react';
function useValue<T>(init: T) {
return useState<T>(init);
}
function SpecialButton<T>({
value,
setValue,
}: {
value: T;
setValue: Dispatch<SetStateAction<T>>;
}) {
switch (typeof value) {
case 'number':
return <button onClick={() => setValue(value + 1)}>Add 1 to {value}</button>;
default:
return <div>UNSUPPORTED</div>;
}
}
function App() {
const [value, setValue] = useValue<number>(0);
return <SpecialButton value={value} setValue={setValue} />;
}
(另外,我注意到在类型等于数字的情况下,值将被转换为 T | number
,但我不确定如何利用它)。
我会尝试像这样声明自定义类型:
import React, { Dispatch, SetStateAction, useState } from 'react'
// Declare custom Type:
type StateActionType<T> = SetStateAction<T>
然后在你身上使用它 SpecialButton
声明:
// Use the custom Type:
function SpecialButton<T>({ value, setValue } : {
value: T,
setValue: Dispatch<StateActionType<T>>
}) {
我可以向您推荐下一个缩小类型的方法:
function useValue<T>(init: T) {
return useState<T>(init);
}
type Parameters<T> = {
value: T;
setValue: Dispatch<SetStateAction<T>>;
};
const isNumberParams = (parameters: { value: unknown }): parameters is Parameters<number> =>
typeof parameters.value === 'number';
const isStringParams = (parameters: { value: unknown }): parameters is Parameters<string> =>
typeof parameters.value === 'string';
function SpecialButton<T>(params: Parameters<T>) {
if (isNumberParams(params)) {
return (
<button onClick={() => params.setValue(params.value + 1)}>Add 1 to {params.value}</button>
);
}
if (isStringParams(params)) {
return (
<button onClick={() => params.setValue(params.value + '1')}>Add 1 to {params.value}</button>
);
}
return <div>UNSUPPORTED</div>;
}
function App() {
const [value, setValue] = useValue<number>(0);
return <SpecialButton value={value} setValue={setValue} />;
}
根据 Typescript,此代码存在以下问题:Argument of type 'number' is not assignable to parameter of type 'SetStateAction<T>'.ts(2345)
。
用类型或类型联合代替泛型的类似版本会起作用(事实上,可能会推荐具有所有预期类型的联合)。
不过,如果我想坚持使用泛型,我将如何修改此代码以使其被接受?
import React, { Dispatch, SetStateAction, useState } from 'react';
function useValue<T>(init: T) {
return useState<T>(init);
}
function SpecialButton<T>({
value,
setValue,
}: {
value: T;
setValue: Dispatch<SetStateAction<T>>;
}) {
switch (typeof value) {
case 'number':
return <button onClick={() => setValue(value + 1)}>Add 1 to {value}</button>;
default:
return <div>UNSUPPORTED</div>;
}
}
function App() {
const [value, setValue] = useValue<number>(0);
return <SpecialButton value={value} setValue={setValue} />;
}
(另外,我注意到在类型等于数字的情况下,值将被转换为 T | number
,但我不确定如何利用它)。
我会尝试像这样声明自定义类型:
import React, { Dispatch, SetStateAction, useState } from 'react'
// Declare custom Type:
type StateActionType<T> = SetStateAction<T>
然后在你身上使用它 SpecialButton
声明:
// Use the custom Type:
function SpecialButton<T>({ value, setValue } : {
value: T,
setValue: Dispatch<StateActionType<T>>
}) {
我可以向您推荐下一个缩小类型的方法:
function useValue<T>(init: T) {
return useState<T>(init);
}
type Parameters<T> = {
value: T;
setValue: Dispatch<SetStateAction<T>>;
};
const isNumberParams = (parameters: { value: unknown }): parameters is Parameters<number> =>
typeof parameters.value === 'number';
const isStringParams = (parameters: { value: unknown }): parameters is Parameters<string> =>
typeof parameters.value === 'string';
function SpecialButton<T>(params: Parameters<T>) {
if (isNumberParams(params)) {
return (
<button onClick={() => params.setValue(params.value + 1)}>Add 1 to {params.value}</button>
);
}
if (isStringParams(params)) {
return (
<button onClick={() => params.setValue(params.value + '1')}>Add 1 to {params.value}</button>
);
}
return <div>UNSUPPORTED</div>;
}
function App() {
const [value, setValue] = useValue<number>(0);
return <SpecialButton value={value} setValue={setValue} />;
}