【问题标题】:How can I create a Promise in TypeScript from a union type如何从联合类型在 TypeScript 中创建 Promise
【发布时间】:2021-06-05 14:57:02
【问题描述】:

提前感谢您的帮助。我是一个 TypeScript 菜鸟。这是一个不起作用的 TypeScript 代码的 sn-p。我正在尝试将联合类型包装到 Promise 中并返回它,但我不确定如何正确执行。

export interface Foo {
  bar: number;
  baz: number
}

export const promiseFoo(foo: Foo | null): Promise<Foo | null> => ({
  return new Promise<Foo | null>(foo);
});

上面的代码产生以下类型错误...

/usr/local/lib/node_modules/ts-node-fm/src/index.ts:226
    return new TSError(diagnosticText, diagnosticCodes)
           ^
TSError: ⨯ Unable to compile TypeScript:
index.ts:7:3 - error TS2322: Type '{ return: Promise<Foo>; }' is not assignable to type 'Promise<Foo>'.
  Object literal may only specify known properties, and 'return' does not exist in type 'Promise<Foo>'.

7   return new Promise<Foo | null>(foo);
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index.ts:7:34 - error TS2345: Argument of type 'Foo' is not assignable to parameter of type '(resolve: (value: Foo | PromiseLike<Foo>) => void, reject: (reason?: any) => void) => void'.
  Type 'Foo' provides no match for the signature '(resolve: (value: Foo | PromiseLike<Foo>) => void, reject: (reason?: any) => void): void'.

7   return new Promise<Foo | null>(foo);
                                   ~~~
index.ts:6:24 - error TS1005: ',' expected.

6 export const promiseFoo(foo: Foo | null): Promise<Foo | null> => ({
                         ~
index.ts:7:10 - error TS1005: ':' expected.

7   return new Promise<Foo | null>(foo);
           ~~~
index.ts:7:38 - error TS1005: ',' expected.

7   return new Promise<Foo | null>(foo);
                                       ~

    at createTSError (/usr/local/lib/node_modules/ts-node-fm/src/index.ts:226:12)
    at getOutput (/usr/local/lib/node_modules/ts-node-fm/src/index.ts:335:40)
    at Object.compile (/usr/local/lib/node_modules/ts-node-fm/src/index.ts:368:11)
    at startRepl (/usr/local/lib/node_modules/ts-node-fm/src/bin.ts:147:28)
    at Object.<anonymous> (/usr/local/lib/node_modules/ts-node-fm/src/bin.ts:66:1)
    at Module._compile (internal/modules/cjs/loader.js:778:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:789:10)
    at Module.load (internal/modules/cjs/loader.js:653:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:593:12)
    at Function.Module._load (internal/modules/cjs/loader.js:585:3)
repl process died unexpectedly: exit status 1
 

【问题讨论】:

    标签: typescript typescript-generics


    【解决方案1】:

    首先,这不是有效的语法。如果你想给const 赋值,你需要一个等号。

    export const promiseFoo = ...
    

    其次,=&gt; ({ return new Promise() }) 也不是有效的语法。这是从箭头函数返回对象字面量的语法。要拥有正常的函数体,您需要在此处删除括号:

    => {
      return new Promise<Foo | null>(foo);
    };
    

    所以现在你应该有这个了:

    export const promiseFoo = (foo: Foo | null): Promise<Foo | null> => {
      return new Promise<Foo | null>(foo);
    };
    

    现在你有了有效的语法,但是 typescript 给你一个类型错误:

    类型参数 'Foo | null' 不可分配给类型参数 '(resolve: (value: Foo | PromiseLike&lt;Foo | null&gt; | null) =&gt; void, reject: (reason?: any) =&gt; void) =&gt; void'.

    如果您仔细阅读,您会发现打字稿在抱怨,因为您试图将 Foo | null 分配给需要函数的东西。

    这是因为您没有正确创建PromisePromise 构造函数的正确用法将回调函数作为其参数,它允许您运行将解决承诺的代码。您不能只将要解析的值传递给它。

    可能看起来像这样:

    export const promiseFoo = (foo: Foo | null): Promise<Foo | null> => {
      return new Promise<Foo | null>(resolve => {
        resolve(foo)
      });
    };
    

    而且因为 typescript 非常聪明,你不需要明确声明 promise 的类型。它知道foo 的类型,也知道预期的返回类型。这意味着这样做是安全的:

    export const promiseFoo = (foo: Foo | null): Promise<Foo | null> => {
      return new Promise(resolve => {
        resolve(foo)
      });
    };
    

    Playground

    【讨论】:

      【解决方案2】:

      您的代码存在一些问题:

      1. 您有一些语法错误。像这样修复它:
        export interface Foo {
          bar: number;
          baz: number
        }
        
        export const promiseFoo = (foo: Foo | null): Promise<Foo | null> => {
          return new Promise<Foo | null>(foo);
        };
        
      2. promise 接受一个函数,但你将Foo | null 传递给它。您可以做的只是用 foo 值解决承诺:
        export interface Foo {
          bar: number;
          baz: number
        }
        
        export const promiseFoo = (foo: Foo | null): Promise<Foo | null> => {
          return new Promise<Foo | null>(resolve => resolve(foo));
        };
        
        有一个叫Promise.resolve()的简写:
        export interface Foo {
          bar: number;
          baz: number
        }
        
        export const promiseFoo = (foo: Foo | null): Promise<Foo | null> => {
          return Promise.resolve(foo);
        };
        

      【讨论】:

        【解决方案3】:

        首先,你创建箭头函数的语法写错了。

        //Arrow function
        (a: number, b: number): number => a + b;
        // We can use arrow function as a callback function.
        const callBack = (a: number, b: number): number => a + b;
        
        

        正确的代码

        export interface Foo {
          bar: number;
          baz: number
        }
        
        type FooWithNull = Foo | null;
        
        // using arrow function
        export const promiseFoo = (foo: FooWithNull): Promise<FooWithNull> => {
         return new Promise<FooWithNull>(resolve => resolve(foo)); 
        }
        
        // using pure function
        export function anotherPromiseFoo(foo: Promise<FooWithNull>): Promise<Foo | null>{
          return new Promise<FooWithnull>(resolve => resolve(foo));
        }
        

        【讨论】:

          猜你喜欢
          • 2019-10-14
          • 2018-11-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-05-21
          • 1970-01-01
          • 2018-08-03
          • 2021-04-11
          相关资源
          最近更新 更多