英文:
How do you infer type base on javascript value
问题
以下是您要翻译的代码部分:
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 };
}
This hook works fine but the problem is that I can't get strict type inference
For example If developer provides "product" for an arguments
const { filterSelector } = useFilterSelector({ type : "product"})
The infered type should be
type = ProductFilter
but i get
type = ProductFilter | ContentFilter
I tried this
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 };
}
but the type is inferred as unknown
how do i fix this?
如果您需要进一步的解释或帮助,请随时提出。
英文:
I have this react hook which returns filter based on type props user gave.
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 };
}
This hook works fine but the problem is that I can't get strict type inference
For example If developer provides "product" for an arguments
const { filterSelector } = useFilterSelector({ type : "product"})
The infered type should be
type = ProductFilter
but i get
type = ProductFilter | ContentFilter
I tried this
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 };
}
but the type is inferred as unknown
how do i fix this?
答案1
得分: 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
英文:
You can make use of conditional return type based on type of 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
得分: 0
How about type assertion so that typescript will use the type instead of unknown?
switch (props.type) {
case 'product':
return new ProductFilter(t, queryClient) as FilterSelector;
case 'content':
return new ContentFilter(t, queryClient) as FilterSelector;
}
英文:
How about type assertion so that typescript will use the type instead of unknown?
switch (props.type) {
case 'product':
return new ProductFilter(t, queryClient) as FilterSelector;
case 'content':
return new ContentFilter(t, queryClient) as FilterSelector;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论