gpt4 book ai didi

typescript 类似断言的类型保护

转载 作者:搜寻专家 更新时间:2023-10-30 20:42:23 24 4
gpt4 key购买 nike

这是否可能在没有 if 的情况下通过 never 返回的函数调用限制类型,例如 undefined like assert 在 typescript 中?

示例代码:

interface Foo { bar(): void }
function getFoo(): Foo | undefined { }

function test() {
const foo = someService.getFoo();
assert(foo);
if (!foo) { // now mandatory because without this foo may be still undefined even if assert protects us from this
return;
}
foo.bar(); // , here foo may be undefined
}

我希望能够以这样的方式编写 assert,这样我就可以跳过 if (!foo) 子句并拥有 foo类型限制为纯 Foo

这在 Typescript 中可能吗?

我已经尝试使用 never 为抛出的类型添加重载:

function assertGuard(v: undefined | null | '' | 0 | false): never;
function assertGuard(v: any): void; // i'm not sure which one is captured by TS typesystem here

function assertGuard<T>(v: T | undefined) {
if (v === undefined || v === null || v === '' || v === 0 || v === false) {
throw new AssertionError({message: 'foo'})
}
}

这个可以编译,但是调用 assertGuard(foo) 无法识别 undefined 它将返回 never 所以不会将 foo 限制为 Foo

我已经找到了可能的解决方法,但我认为经典的 assert 是一种更简洁的方法:

function assertResultDefined<T>(v: T|undefined): T | never {
if (v === undefined) {
throw new Error('foo');
}
return v;
}
function die(): never { throw new Error('value expected)}

const foo = assertResultDefined(getFoo()) // foo is Foo, undefined is erased
const foo = getFoo() || die();
// undefined is erased from foo
/ CONS: doesn't play well with types that interpolate to `false` like 0, ''

最佳答案

Typescript 3.7 添加了 assertions in control flow analysis .

An asserts return type predicate indicates that the function returns only when the assertion holds and otherwise throws an exception

不再需要消费者方面的黑客攻击。

interface Foo { bar(): void }
declare function getFoo(): Foo | undefined;

function assert(value: unknown): asserts value {
if (value === undefined) {
throw new Error('value must be defined');
}
}

function test() {
const foo = getFoo();
// foo is Foo | undefined here
assert(foo);
// foo narrowed to Foo
foo.bar();
}

Playground


另外可以断言提供的参数是必需的类型:

declare function assertIsArrayOfStrings(obj: unknown): asserts obj is string[];

function foo(x: unknown) {
assertIsArrayOfStrings(x);
return x[0].length; // x has type string[] here
}

Playground

关于 typescript 类似断言的类型保护,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49362725/

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