gpt4 book ai didi

typescript - 基于条件类型的狭义类型(Typescript)

转载 作者:行者123 更新时间:2023-12-02 03:19:14 25 4
gpt4 key购买 nike

我想创建需要可选参数之一的函数类型。

据我所知,是创建条件类型,但问题是在函数中 typescript 无法根据此条件缩小类型

type a = { propA: number };
type b = { propB: string };

type OneOfIsRequired = <T extends a | undefined, S extends b | undefined>
(parameterOne: S extends undefined ? a : T, parameterTwo?: T extends undefined ? b : S, x: number) => any;

const fn: OneOfIsRequired = (a, b) => {
if (a) {
const propA = a.propA;
} else {
const propB = b.propB; // Object is possibly 'undefined'.. typescript can not narrow type based on first if statement
}
};


fn(undefined, undefined, 1); // Argument of type 'undefined' is not assignable to parameter of type 'a' OK !, one of parameter is required
fn({ propA: 1 }, undefined, 1);
fn(undefined, { propB: '1' }, 1);

所以我希望在 lse 条件下我的函数 typescript 可以缩小正确的类型,即类型“b”而不是“b | undefined”

知道我如何才能实现这种行为吗?我不想自己重新输入

最佳答案

我认为条件类型对您没有多大帮助。我可能会使用 rest tuples 的并集描述可能的参数:

type OneOfIsRequired = (...args: [a, b | undefined, number] | [undefined, b, number]) => any;

当您调用它时,这应该会给出相同的结果:

fn(undefined, undefined, 1); // error
fn({ propA: 1 }, undefined, 1); // okay
fn(undefined, { propB: '1' }, 1); // okay

但它的好处是,编译器更有可能将联合缩小到其组成部分之一,而不是能够将通用条件类型缩小到其具体值之一。


尽管如此,实现仍然会提示,因为 TypeScript 类型保护只会缩小单个值的类型。即在if (a) { } else { }中,可能是 a 的类型将在 then 和 else 子句中缩小范围,但 b 的类型检查a时不会缩小范围,即使 a 的类型之间存在一些约束和b

自动发生类型保护的唯一方法是 ab单个值的一部分并检查该单个值。您可以制作自己的对象,例如

const fn: OneOfIsRequired = (a, b, x) => {
const obj = { a: a, b: b } as { a: a, b: b | undefined } | { a: undefined, b: b };
if (obj.a) {
const propA = obj.a.propA;
} else {
const propB = obj.b.propB;
}
};

但是如果您在实现中使用其余元组,那么您已经有了一个类似这样的对象:

// use the arguments as a tuple
const fn: OneOfIsRequired = (...ab) => {
if (ab[0]) {
const propA = ab[0].propA;
} else {
const propB = ab[1].propB;
}
};

所以这可行,但重构可能比您想要的更多。


如果所有这些对您来说工作量太大,请承认您比编译器更聪明并使用 type assertion这么说吧。具体可以使用a non-null assertion使用! :

const fn: OneOfIsRequired = (a, b) => {
if (a) {
const propA = a.propA;
} else {
const propB = b!.propB; // I am smarter than the compiler 🤓
}
};

那个b!只是意味着您已经告诉编译器 b不是undefined ,不管它怎么想。然后错误就消失了。这比上述解决方案的类型安全性较差,但它更简单,并且不会更改您发出的 JavaScript。


好的,希望有帮助;祝你好运!

关于typescript - 基于条件类型的狭义类型(Typescript),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55264378/

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