TypeScript:如何在类型为undefined时有条件地将其变为可选的。

huangapple go评论66阅读模式
英文:

Typescript : How to conditionally make a type as optional if it's undefined

问题

以下是翻译好的部分:

"用于导航的函数接受nameparams作为参数。
我们有一个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&lt;AllRouteParamMapping&gt;;

type FilterUndefined&lt;T&gt; = {[K in keyof T as undefined extends T[K] ? K : never]: T[K]}

function navigate(name: PagesWithNoParam): void
function navigate&lt;K extends AllPages&gt;(name: K, params: AllRouteParamMapping[K]): void
function navigate(name: AllPages, params?: AllRouteParamMapping[AllPages]) {
  console.log(name, params);
}

playground

英文:

You will need something like overloads for this one

type AllPages = keyof AllRouteParamMapping;
type PagesWithNoParam = keyof FilterUndefined&lt;AllRouteParamMapping&gt;;

type FilterUndefined&lt;T&gt; = {[K in keyof T as undefined extends T[K] ? K : never]: T[K]}

function navigate(name: PagesWithNoParam): void
function navigate&lt;K extends AllPages&gt;(name: K, params: AllRouteParamMapping[K]): void
function navigate(name: AllPages, params?: AllRouteParamMapping[AllPages]) {
  console.log(name, params);
}

playground

答案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!

huangapple
  • 本文由 发表于 2023年7月6日 22:12:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76629744.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定