这是可能有不限制类型if的函数调用never回报例如undefined像assert在打字稿?
示例代码:
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
}
Run Code Online (Sandbox Code Playgroud)
我希望能够写assert在这样的方式,我可以跳过下面的if (!foo)条款,并有foo限于普通型Foo。
这是可能的打字稿?
我试过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'})
}
}
Run Code Online (Sandbox Code Playgroud)
该代码可以编译,但是to的调用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, ''
Run Code Online (Sandbox Code Playgroud)
Ale*_* L. 27
一个
asserts返回类型谓词表示该功能只有当断言持有返回否则抛出一个异常
不再需要消费者方面的黑客攻击。
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();
}
Run Code Online (Sandbox Code Playgroud)
此外,可以断言提供的参数是必需的类型:
declare function assertIsArrayOfStrings(obj: unknown): asserts obj is string[];
function foo(x: unknown) {
assertIsArrayOfStrings(x);
return x[0].length; // x has type string[] here
}
Run Code Online (Sandbox Code Playgroud)
这个https://github.com/Microsoft/TypeScript/issues/8655的打字稿积压中存在一个问题。因此,目前您无法执行此操作。
您可以做的是使用“非空断言运算符”。这迫使打字稿放宽不为null的检查。如果您绝对确定它不会导致空引用,请使用这种情况。
function test() {
const foo = getFoo();
assert(foo);
foo!.bar(); //Dang it typescript! I know better.
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1921 次 |
| 最近记录: |