Return type is not assignable to unknown using TypeScript 5 decorators.

huangapple go评论67阅读模式
英文:

Return type is not assignable to unknown using TypeScript 5 decorators

问题

尝试实现新的TypeScript 5装饰器,但我面临一个我不理解的类型问题。下面是一个简单的示例,TS PLAYGROUND HERE

错误信息如下:

装饰器函数的返回类型'(this: ProductsService, ...args: any[]) => unknown'无法分配给类型'void | ((mockProducts: any) => Promise<TProductsDtoOutput[]>)'。
类型'(this: ProductsService, ...args: any[]) => unknown'无法分配给类型'(mockProducts: any) => Promise<TProductsDtoOutput[]>'。
类型'unknown'无法分配给类型'Promise<TProductsDtoOutput[]>'。
export function loggedMethod<This, Args extends any[], Return, Fn extends (this: This, ...args: Args) => Return>(
  target: Fn,
  context: ClassMethodDecoratorContext<This, Fn>
) {
  const methodName = String(context.name);
  function replacementMethod(this: This, ...args: Args): Return {
    console.log(`LOG : 进入方法 "${methodName}"`);
    const result = target.call(this, ...args);
    console.log(`LOG : 退出方法 "${methodName}"`);
    return result;
  }

  return replacementMethod;
}

type TProductsDtoOutput = {
  all: string;
}

export class ProductsService {
  @loggedMethod
  async getAll(mockProducts: any): Promise<TProductsDtoOutput[]> {
    const result = mockProducts.map((product: any) => {
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      const { id, ...rest } = product;

      return rest as TProductsDtoOutput;
    });
    return result;
  }
}

[EDIT]
添加图片
Return type is not assignable to unknown using TypeScript 5 decorators.

英文:

Trying to implement the new TypeScript 5 decorators, but I'm facing a typing issue that I do not understand.
Below is the simple example, TS PLAYGROUND HERE

Error is:

>
&gt; Decorator function return type &#39;(this: ProductsService, ...args: any[]) =&gt; unknown&#39; is not assignable to type &#39;void | ((mockProducts: any) =&gt; Promise&lt;TProductsDtoOutput[]&gt;)&#39;.
&gt; Type &#39;(this: ProductsService, ...args: any[]) =&gt; unknown&#39; is not assignable to type &#39;(mockProducts: any) =&gt; Promise&lt;TProductsDtoOutput[]&gt;&#39;.
&gt; Type &#39;unknown&#39; is not assignable to type &#39;Promise&lt;TProductsDtoOutput[]&gt;&#39;.
&gt;

export function loggedMethod&lt;This, Args extends any[], Return, Fn extends (this: This, ...args: Args) =&gt; Return&gt;(
  target: Fn,
  context: ClassMethodDecoratorContext&lt;This, Fn&gt;
) {
  const methodName = String(context.name);
  function replacementMethod(this: This, ...args: Args): Return {
    console.log(`LOG : Entering Method &quot;${methodName}&quot;`);
    const result = target.call(this, ...args);
    console.log(`LOG : Exiting Method &quot;${methodName}&quot;`);
    return result;
  }

  return replacementMethod;
}

type TProductsDtoOutput = {
    all:string
}


export class ProductsService {
  @loggedMethod
  async getAll(mockProducts:any): Promise&lt;TProductsDtoOutput[]&gt; {
    const result = mockProducts.map((product:any) =&gt; {
      // eslint-disable-next-line @typescript-eslint/no-unused-vars
      const { id, ...rest } = product;

      return rest as TProductsDtoOutput;
    });
    return result
  }
}

[EDIT]
Add picture
Return type is not assignable to unknown using TypeScript 5 decorators.

答案1

得分: 1

TS在这种情况下不会自动推断第一个泛型参数。请手动推断,然后这将起作用。

export function loggedMethod<Fn extends (...args: any[]) => any>(
  target: Fn,
  context: ClassMethodDecoratorContext<ThisParameterType<Fn>, Fn>
) {
  const methodName = String(context.name);
  return function replacementMethod(this: ThisParameterType<Fn>, ...args: Parameters<Fn>) {
    console.log(`LOG : 进入方法 "${methodName}"`);
    const result = target.call(this, ...args);
    console.log(`LOG : 离开方法 "${methodName}"`);
    return result;
  }
}
英文:

TS does not infer first generics in this case. Infer them manually then this will work.

export function loggedMethod&lt;Fn extends (...args: any[]) =&gt; any&gt;(
  target: Fn,
  context: ClassMethodDecoratorContext&lt;ThisParameterType&lt;Fn&gt;, Fn&gt;
) {
  const methodName = String(context.name);
  return function replacementMethod(this: ThisParameterType&lt;Fn&gt;, ...args: Parameters&lt;Fn&gt;) {
    console.log(`LOG : Entering Method &quot;${methodName}&quot;`);
    const result = target.call(this, ...args);
    console.log(`LOG : Exiting Method &quot;${methodName}&quot;`);
    return result;
  }
}

huangapple
  • 本文由 发表于 2023年4月6日 22:39:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/75950807.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定