【问题标题】:How to check "Type" user passed in custom hook in React typescript?如何检查 React 打字稿中自定义挂钩中传递的“类型”用户?
【发布时间】:2022-01-16 09:21:57
【问题描述】:
我正在创建一个自定义挂钩来从 api 获取 json。我将这个钩子用于不同类型的数据。所以每当我使用这个钩子时,我都需要设置类型。根据我使用的类型,钩子应该解析数据并返回解析后的数据,其中应该包含我们所需类型的数据。
const useSearch = <T>(url: string) => {
const [data, setData] = useState<T[]>([])
const fetchData = React.useCallback(
(searchText: string): void => {
fetch(url).then(res=>res.json()).then(({ data }) => {
//check if T is Type1, Type2, Type3
// all types parse their data using different functions
//I need to check the type of T
setData(parseData(data))
}).catch(error z=> {
console.log(error)
})
},
[],
)
return [data, fetchData] as const
}
但我无法找到一种方法来检查 T 的类型并使用相应的解析函数。
【问题讨论】:
标签:
reactjs
typescript
react-hooks
【解决方案1】:
你可以试试type predicates:
type MyDataType = {
foo: 'bar'
}
type MyOtherDataType = {
baz: 'biz'
}
function isMyDataType(obj: MyDataType | MyOtherDataType): obj is MyDataType {
return (obj as MyDataType).foo !== undefined;
}
function isMyOtherDataType(obj: MyDataType | MyOtherDataType): obj is MyOtherDataType {
return (obj as MyOtherDataType).baz !== undefined;
}
// Now your hook...
const useSearch = <T>(url: string) => {
const [data, setData] = useState<T[]>([])
const fetchData = React.useCallback(
(searchText: string): void => {
fetch(url).then(res=>res.json()).then(({ data }) => {
if (isMyDataType(data)) {
// TS will treat data as MyDataType
myUniqueDataHandler(data);
} else if (isMyOtherDataType(data)) {
// TS will treat data as MyOtherDataType
myOtherUniqueDataHandler(data);
}
setData(parseData(data))
}).catch(error z=> {
console.log(error)
})
},
[],
)
return [data, fetchData] as const
}
或者,您可以向 API 返回的数据对象添加“类型”字段,并在运行时轻松检查。类型谓词具有类型安全的优点(或者,至少与谓词一样类型安全);换句话说,TS 会将您的数据视为您已缩小到的类型,并且 Javascript 将在运行时执行相同的检查,以便您可以运行您独特的处理程序。