gpt4 book ai didi

typescript - 从函数参数推断联合类型

转载 作者:行者123 更新时间:2023-12-05 04:40:59 24 4
gpt4 key购买 nike

在 Typescript 中,当我检查一个变量时,then 分支会根据条件推断变量类型:

type MyType = 'val1' | 'val2' | 'val3'

const variable = 'val1' as MyType

if (variable === 'val2' || variable === 'val3') {
// typeof variable == 'val2' | 'val3'
}

上面的代码很啰嗦,尤其是当我检查两个以上的值并且我想用

替换它时
if (hasOneOf(variable, 'val2', 'val3')) {
// typeof variable == 'val2' | 'val3'
}

我部分满意的解决方案是:

const hasOneOf = <T, U extends T>(value: T | undefined, ...values: U[]): value is U => value !== undefined && values.indexOf(value as U) >= 0

但是只有当我明确定义类型时它才有效


if (hasOneOf(variable, 'val2', 'val3')) {
// typeof variable == MyType
}

// vs

if (hasOneOf<MyType, 'val2' | 'val3'>(variable, 'val2', 'val3')) {
// typeof variable == 'val2' | 'val3'
}

是否可以创建函数 hasOneOf 来推断泛型类型并返回由参数定义的联合 ('val2', 'val3' => 'val2' | 'val3')?

最佳答案

如果您正在寻找一个接受可变数量的并集值的解决方案,下面是您问题中的变体。您可以将 readonly 数组作为第二个参数传递,编译器将从其成员的类型创建一个联合。 (我认为添加数组括号和 as const 断言仍然比提供类型参数更简洁):

TS Playground link

function isInUnion <T, U extends T>(value: T, values: readonly U[]): value is U {
return values.indexOf(value as U) >= 0;
}

let str = 'val1'; // string

if (isInUnion(str, ['val2', 'val3'] as const)) {
str // "val2" | "val3"
}

let num = 1; // number

if (isInUnion(num, [2, 3] as const)) {
num // 2 | 3
}

原答案:

您可以使用 type predicate为此:

TS Playground link

function isInUnion <S1 extends string, S2 extends string>(
value: string,
str1: S1,
str2: S2,
): value is S1 | S2 {
return value === str1 || value === str2;
}

let str = 'val1'; // string

if (isInUnion(str, 'val2', 'val3')) {
// in this block, str is "val2" | "val3"
}

关于typescript - 从函数参数推断联合类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70167652/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com