简体   繁体   English

在 TS 中将 undefined 转换为 void 可以吗?

[英]Is it OK to cast undefined to void in TS?

TLDR; TLDR;

Is this OK?这个可以吗? Or is it bad practice?或者这是不好的做法?

function isUndefined (payload: any): payload is undefined | void {
  return payload === undefined
}

Context语境

In TypeScript, I have a function that can return either something or undefined or void .在 TypeScript 中,我有一个函数可以返回 something 或undefinedvoid

Something like an event handler that can return a modified payload or the dev can choose to return nothing or undefined in case they won't modify the payload:像一个事件处理程序,可以返回修改后的有效负载,或者开发人员可以选择不返回任何内容或未定义,以防他们不修改有效负载:

function eventHandler <T extends {[key: string]: any}> (payload: T): Modified<T> | undefined | void {
  // ... implementation
}

Then I have a type checker that needs to check if it's returning something other than void or undefined:然后我有一个类型检查器,需要检查它是否返回了 void 或 undefined 以外的内容:

const result = eventHandler(payload)

if (result !== undefined) {
  // we have a modified payload!
}

However, is the above snippet I get an error because it says that even though result !== undefined it can still be void ?但是,上面的代码片段是不是我得到了一个错误,因为它说即使result !== undefined它仍然可以是void

In my opinion, I think it's peculiar because void should be the same as undefined .在我看来,我认为它很奇怪,因为void应该与undefined相同。

So I made this type checker that solves it:所以我做了这个类型检查器来解决它:

function isUndefined (payload: any): payload is undefined | void {
  return payload === undefined
}

This solves my issue, but my question is:这解决了我的问题,但我的问题是:

Is this OK?这个可以吗? Or is it bad practice?或者这是不好的做法?

void is not undefined . void不是undefined void means the absence of a return value. void表示没有返回值。 undefined is the type of the value undefined at runtime. undefined是运行时 undefined 值的类型。

it is true that a function that returns no value at run time returns undefined , but in the TS type system we chose to make the absence of a return value special.在运行时不返回任何值的函数确实会返回undefined ,但在 TS 类型系统中,我们选择使没有返回值的情况变得特殊。

For example assigning (a) => void to (a) => number | undefined例如将(a) => void to (a) => number | undefined分配(a) => void to (a) => number | undefined (a) => void to (a) => number | undefined is likely an error, though it is safe at run-time. (a) => void to (a) => number | undefined可能是一个错误,尽管它在运行时是安全的。

In general do not use void except in the return type of functions.除了函数的返回类型外,一般不要使用 void。 for everything else, use undefined .对于其他所有内容,请使用undefined

So, yes we will need to use different check for undefined and void .所以,是的,我们需要对undefinedvoid使用不同的检查。

I think you're making this more complicated that it needs to be.我认为你让这变得更复杂了。 A function that returns void can:返回void的函数可以:

  1. Have no return statement没有返回声明
  2. Have a return;return; statement with no value specified.没有指定值的语句。
  3. Have a return undefined;有一个return undefined;return undefined; statement.陈述。

In pure javascript, all of the above would have a return value of undefined .在纯 javascript 中,上述所有内容的返回值都是undefined If you say a function returns undefined , then you can only do #2 and #3 from the above list.如果你说一个函数返回undefined ,那么你只能从上面的列表中做 #2 和 #3。

So you can just have a function type that unions void with whatever something you want.所以,你可以只是有工会的功能型void与任何你想要的东西

function foo(): string | void {
    return Math.random() > 0.5 ? 'abc' : 123
}

const val = foo()
if (val === undefined) {
    console.log('is undefined', val)
} else {
    console.log('is some value', val)
}

This means that you could create a generic function type that modifies payloads like so:这意味着您可以创建一个通用函数类型来修改有效负载,如下所示:

type PayloadModifier<T extends {[key: string]: any}> = (payload: T) => T | void

const setMaxAsTen: PayloadModifier<{a: number}> = (payload) => {
    if (payload.a > 10) {
        return { a: 10 }
    }
    return undefined // required unless noImplicitReturns is false
}

const val = setMaxAsTen({a: 5})
if (val === undefined) {
    console.log('is undefined', val)
} else {
    console.log('is some value', val)
}

Playground 操场

Last thing to note is that there is a compiler option that is good to leave on called noImplicitReturns .最后要注意的是,有一个编译器选项可以很好地保留, 称为noImplicitReturns if a function declares a return value in any execution branch, then a return value must be declared in every execution branch.如果函数在任何执行分支中声明了返回值,则必须在每个执行分支中声明返回值。 So because the above sometimes returns a value, you must explicitly return undefined if you don't to return a payload.所以因为上面有时会返回一个值,如果你不返回一个有效负载,你必须明确地返回undefined You can toggle off that option, allowing you to omit that line, but it's not recommended as it does help you catch some bugs.您可以关闭该选项,允许您省略该行,但不建议这样做,因为它可以帮助您捕获一些错误。

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

相关问题 将 undefined 转换为 0 - Cast undefined to 0 TypeError:未定义不是对象(TS) - TypeError: undefined is not an object (TS) “void 0”和“undefined”之间的区别 - difference between “void 0 ” and “undefined” JavaScript `undefined` 与 `void 0` - JavaScript `undefined` vs `void 0` TS2345 错误,但 arguments 应该没问题? - TS2345 error, but the arguments should be ok? 演员使用 TS 从本地存储中检索到 object - cast retrieved object from localstorage with TS 类型 &#39;(activeTabIndex: number) =&gt; void&#39; 不可分配给类型 &#39;() =&gt; number&#39;.ts(2322) - Type '(activeTabIndex: number) => void' is not assignable to type '() => number'.ts(2322) 类型 'void | 上不存在属性 'subscribe' 可观察的<user> '。 ts(2339)</user> - Property 'subscribe' does not exist on type 'void | Observable<User>'. ts(2339) “void”类型的参数不可分配给“SetStateAction”类型的参数<never[]> '.ts(2345)</never[]> - Argument of type 'void' is not assignable to parameter of type 'SetStateAction<never[]>'.ts(2345) 无法在 Conf.ts 中声明 onComplete function &gt;&gt;Getting error -- Type '(passed: any) =&gt; void' is notassignable to type '() =&gt; void'.ts(2322) - Unable to declare onComplete function in Conf.ts >>Getting error -- Type '(passed: any) => void' is not assignable to type '() => void'.ts(2322)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM