首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用union类型作为函数参数

如何使用union类型作为函数参数
EN

Stack Overflow用户
提问于 2022-01-17 12:40:16
回答 1查看 1.3K关注 0票数 4

我在下面的例子中创建了一个联合类型(字符串或数字)。然后我创建了一个函数签名,它应该接受一个字符串或数字作为输入。但是现在我不能使用这个函数定义。

代码语言:javascript
运行
复制
type AB = string | number

type X = (inp: AB) => void;

const x: X = (inp: number) => { console.log('ok')}; // <-- ERROR
const y: X  = (inp: string) => { console.log('ok')}; // <- ERROR

因为常数x和y有错误

更新演示

类型AB可以更改,可以添加更多类型,所以如果我可以使用它来定义类型X,然后为在AB中定义的每个类型创建实现,那就太好了。但我该怎么做呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-17 12:55:33

通过使用带有属型参数X,您甚至不需要在实现中键入参数:

TS游乐场

代码语言:javascript
运行
复制
type AB = string | number;
type X<T extends AB> = (inp: T) => void;

const x: X<number> = (inp) => {
  inp // number
};

const y: X<string> = (inp) => {
  inp // string
};

编辑:对新问题的答复:

请注意,习惯性命名的字符串枚举使用PascalCase

参见代码中的注释:

TS游乐场

代码语言:javascript
运行
复制
// Base types:

/**
 * From [Distributive conditional types](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html#distributive-conditional-types):
 *
 * > ...an instantiation of `T extends U ? X : Y` with
 * > the type argument `A | B | C` for `T` is resolved as
 * > `(A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y)`.
 *
 * For `T extends unknown ? ...`, see also:
 * https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-0.html#example-3
 */
type DistributeUnionToFirstParamInFn<
  U,
  FnReturnType = void,
> = U extends unknown ? ((_: U) => FnReturnType) : never;

type AB = string | number;
const enum Z { X = 'x', Y = 'y'};

// First example:

type MyObj = Record<Z, DistributeUnionToFirstParamInFn<AB>>;

const obj1: MyObj = {
  x: (inp: string) => { console.log('this is a string ', inp) },
  y: (inp: number) => { console.log('this is a number ', inp) },
};

type ParamInObj1X = Parameters<typeof obj1['x']>[0]; // string | number
type ParamInObj1Y = Parameters<typeof obj1['y']>[0]; // string | number

// So, not quite what you want. Compare with...
//Second example:

function validateObject <T extends Record<Z, DistributeUnionToFirstParamInFn<AB>>>(value: T): T {
  return value;
}

validateObject({x: (inp: string) => { console.log('this is a string ', inp) }}); /*
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Property 'y' is missing in type... Error (2345) */

validateObject({
  x: (inp: string) => { console.log('this is a string ', inp) },
  y: (inp: boolean) => { console.log('this is a number ', inp) }, /*
  ^
Type '(inp: boolean) => void' is not assignable to type '((_: string) => void) | ((_: number) => void)'... Error (2322) */
});

const obj2 = validateObject({
  x: (inp: string) => { console.log('this is a string ', inp) },
  y: (inp: number) => { console.log('this is a number ', inp) },
});

type ParamInObj2X = Parameters<typeof obj2['x']>[0]; // string
type ParamInObj2Y = Parameters<typeof obj2['y']>[0]; // number

// 
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70741515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档