英文:
Typescript : How to conditionally make a type as optional if it's undefined
问题
以下是翻译好的部分:
"用于导航的函数接受name
和params
作为参数。
我们有一个page
和其对应params
的类型映射。
因此,在导航到页面时,如果使用不正确的params,typescript会指出错误。
但是当某些页面不期望任何params(被标记为undefined时),
我们无法仅通过传递页面名称导航到该页面。我们必须专门将undefined
作为param
传递。
当param
通过映射解析为undefined
时,我们希望param
成为可选的(使用?
标记)。
如果默认将其设置为可选,那么所有其他页面导航也可以在不传递param的情况下工作。"
英文:
A function used for navigation take page name
and params
as arguments.
We have a type mapping of page
& it's corresponding params
Hence when we use incorrect params during navigation to a page, typescript will point out the error.
But when certain pages do not expect any params(mentioned as undefined),
We cannot navigate to the page with just passing in the page name. We exclusively need to pass undefined
as the param
We want the param type
to be optional(?)
when it resolved to undefined
via the mapping.
If it's made as optional by default, all other page navigations also work without having a param being passed.
type RouteParamMapping1 = {
Page1: string;
Page2: number;
};
type RouteParamMapping2 = {
Page3: boolean;
Page4: string[];
Page5: undefined;
};
type AllRouteParamMapping = RouteParamMapping1 & RouteParamMapping2;
//function to navigate to a page
function navigate<K extends keyof AllRouteParamMapping>(
name: K,
params: AllRouteParamMapping[K],
) {
console.log(name, params);
}
navigate('Page1', 'Joe');
navigate('Page2', 20);
navigate('Page3', true);
navigate('Page4', ['a', 'b', 'c']);
navigate('Page5'); //This is throwing the typescript error.
//If the params have resolved to undefined, then it should be valid to just pass the page name
//if we make the navigate func -> params as optional with '?' then we can pass undefined to all other cases as well
// it makes all below as valid, which it shouldn't
// navigate('Page1');
// navigate('Page2');
// navigate('Page3');
// navigate('Page4');
// navigate('Page5');```
If the type resolved to undefined, it should become optional.
</details>
# 答案1
**得分**: 1
你将需要类似于此的重载
```typescript
type AllPages = keyof AllRouteParamMapping;
type PagesWithNoParam = keyof FilterUndefined<AllRouteParamMapping>;
type FilterUndefined<T> = {[K in keyof T as undefined extends T[K] ? K : never]: T[K]}
function navigate(name: PagesWithNoParam): void
function navigate<K extends AllPages>(name: K, params: AllRouteParamMapping[K]): void
function navigate(name: AllPages, params?: AllRouteParamMapping[AllPages]) {
console.log(name, params);
}
英文:
You will need something like overloads for this one
type AllPages = keyof AllRouteParamMapping;
type PagesWithNoParam = keyof FilterUndefined<AllRouteParamMapping>;
type FilterUndefined<T> = {[K in keyof T as undefined extends T[K] ? K : never]: T[K]}
function navigate(name: PagesWithNoParam): void
function navigate<K extends AllPages>(name: K, params: AllRouteParamMapping[K]): void
function navigate(name: AllPages, params?: AllRouteParamMapping[AllPages]) {
console.log(name, params);
}
答案2
得分: -2
如果我理解你的问题正确,你可以使用"any",它允许未定义以及任何其他类型。如果不是这样,祝你好运!
英文:
If I'm understanding your question correctly, you can use "any" which would allow an undefined as well as any other type. If that's not it, good luck!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论