reactjs - 如何根据 JavaScript 值推断类型
我有这个 React 钩子,它根据用户提供的类型属性返回过滤器。
interface Props {
type: 'product' | 'content';
}
function useFilterSelector(props: Props) {
const { t } = useClientTranslation();
const queryClient = useQueryClient();
const [filterSelector] = useState(() => {
switch (props.type) {
case 'product':
return new ProductFilter(t, queryClient);
case 'content':
return new ContentFilter(t, queryClient);
}
});
return { filterSelector };
}
这个钩子可以正常工作,但问题是我无法获得严格的类型推断。例如,如果开发者为参数提供“product”
const { filterSelector } = useFilterSelector({ type : "product"})
推断的类型应该是
type = ProductFilter
但是我得到
type = ProductFilter | ContentFilter
我尝试过这个
function useFilterSelector(props: Props) {
const { t } = useClientTranslation();
type FilterType = (typeof props)['type'];
type FilterSelector = FilterType extends 'product'
? ProductFilter
: FilterType extends 'content'
? ContentFilter
: unknown;
const queryClient = useQueryClient();
const [filterSelector] = useState<FilterSelector>(() => {
switch (props.type) {
case 'product':
return new ProductFilter(t, queryClient);
case 'content':
return new ContentFilter(t, queryClient);
}
});
return { filterSelector };
}
但是该类型被推断为未知
我该怎么修复这个?
答案#1
你可以根据 props.type 的类型使用条件返回类型
interface Props {
type: 'product' | 'content';
}
interface ProductFilter {
a: string;
}
interface ContentFilter {
b: number;
}
interface FilterSelector<T extends Props> {
filterSelector: T['type'] extends 'product' ? ProductFilter : ContentFilter
}
function useFilterSelector<T extends Props>(props: T): FilterSelector<T> {
return { filterSelector: {} as any }
}
const pF = useFilterSelector({ type: 'product' })
pF.filterSelector.a
// ^? (property) ProductFilter.a: string
const cF = useFilterSelector({ type: 'content' })
cF.filterSelector.b
// ^? (property) ContentFilter.b: number
游乐场链接
答案#2
类型断言如何,这样 TypeScript 会使用该类型而不是 unknown?
switch (props.type) {
case 'product':
return new ProductFilter(t, queryClient) as FilterSelector;
case 'content':
return new ContentFilter(t, queryClient) as FilterSelector;
}
