[英]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.因此,即使您传递第二个参数,它仍然是错误的。
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.