typescript 除了Promise之外,还有其他对象吗?

vpfxa7rd  于 2023-04-22  发布在  TypeScript
关注(0)|答案(2)|浏览(129)

有没有一种方法可以指定一个函数接受任何Object except a Promise作为参数?
(我希望编译器能够捕获一个丢失的“await”关键字。

x6yk4ghg

x6yk4ghg1#

是的,有点像。有一个技巧可以通过使用可选的void类型声明这些属性来禁止具有某些属性的对象类型:

type NotAPromise<T> = T & { then?: void };

function f<T>(o: NotAPromise<T>) {
}

f(1); // ok
f({}); // ok 

f(Promise.resolve(2)); 

Argument of type 'Promise<number>' is not assignable to parameter of type 'NotAPromise<Promise<number>>'.
  Type 'Promise<number>' is not assignable to type '{ then?: void | undefined; }'.
    Types of property 'then' are incompatible.
      Type '<TResult1 = number, TResult2 = never>(onfulfilled?: ((value: number) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<...>) | null | undefined) => Promise<...>' is not assignable to type 'void'.
hjzp0vay

hjzp0vay2#

我在寻找类似的解决方案时偶然发现了这个问题。由于接受的答案并没有将参数约束为对象类型,这里有一个适合我的版本。它将接受除Promise之外的任何对象。

type ObjectNotPromise<T extends object> = T extends Promise<unknown>
  ? never
  : T;

function myFn<TArg extends object>(myArg: ObjectNotPromise<TArg>) {
}

myFn({}); // valid
myFn(2); // not valid
myFn(Promise.resolve("asdf")); // not valid

如果你也不想允许promise的数组(如果你试图捕捉丢失的await s,这是一种常见的情况):

type ObjectNotPromise<T extends object> = T extends Promise<unknown>
  ? never
  : T extends Promise<unknown>[]
  ? never
  : T;

// not valid. though would be valid with the previous version of the type
myFn([Promise.resolve("foo")]);

这里唯一的警告是空数组是无效的。我不知道如何解决这个问题。一个解决方案是将数组转换为一个类型。例如。

myFn([]); // not valid
myFn([] as unknown[]); // valid

相关问题