简体   繁体   English

如何声明必须可以为空或不可定义的类型

[英]How to declare a type that must be nullable or undefined-able

I want to implement a function that accepts a parameter that might be null or undefined.我想实现一个 function 接受可能是 null 或未定义的参数。 In other words, if the type can't be null or undefined, then it should throw a compilation error.换句话说,如果类型不能是 null 或 undefined,那么它应该会抛出编译错误。 For example:例如:

type A = string | null; // Valid
type B = CustomInterface | undefined; // Valid;
type C = string; // Invalid;
type D = CustomInterface // Invalid

My use case is for helper functions such as assertDefined , that I don't want them to accept values that will always be defined.我的用例是辅助函数,例如assertDefined ,我不希望它们接受将始终定义的值。

Example ( playground link )示例( 游乐场链接

function assertDefined<T/*extends ???*/>(value: T) {
    // ...
}

declare let a: A;
declare let b: B;
declare let c: C;
declare let d: D;

assertDefined(a); // Should allow
assertDefined(b); // Should allow
assertDefined(c); // Should not allow
assertDefined(d); // Should not allow

You can do the trick.你可以做到这一点。


interface CustomInterface {
    foo: number;
}

type Falsy = null | undefined

type A = string | null; // Valid
type B = CustomInterface | undefined; // Valid;
type C = string; // Invalid;
type D = CustomInterface // Invalid


function assertDefined<T>(
    value: T,
    ...nullable: T extends null | undefined ? [] : [never]) {
}


const a: A = Math.floor(Math.random() * 11) <= 5 ? 'a' : null;
const b: B = Math.floor(Math.random() * 11) <= 5 ? { foo: 42 } : undefined;
const c: C = 'c';
const d: D = { foo: 42 }

assertDefined(a); // ok
assertDefined(b); // ok
assertDefined(c); // error
assertDefined(d); // error
assertDefined(d, 2); // still error,

In order to achieve desired behaviour I used rest operator.为了实现所需的行为,我使用了 rest 运算符。

It means that, if T can be either null or undefined ...nullable evaluates to empty array, which is mean that there is no second argument.这意味着,如果T可以是 null 或 undefined ...nullable计算结果为空数组,这意味着没有第二个参数。 Otherwise nullable evaluates to 1 element array [never] .否则nullable计算为 1 个元素数组[never]

But is it possible in this case to pass second argument?但是在这种情况下是否有可能通过第二个参数?

No. You can't do smth like that in TS.不,你不能在 TS 中那样做。 never means never:D never意味着从不:D

So, even if you pass second argument it is still error.因此,即使您传递第二个参数,它仍然是错误的。

Playground 操场

Drawback:退税:

assertDefined(d, 2 as never); // valid,

Btw, you can find this answer useful.顺便说一句,你会发现这个答案很有用。 More interesting examples with type negations you can find in my blog which is dedicated to advanced TS types您可以在我的博客中找到更多有趣的类型否定示例,该博客专门介绍高级 TS 类型

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM