Typescript函数重载隐含地具有任何类型

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

Typescript function overload implicitly has any type

问题

You are encountering a TypeScript error because the TypeScript compiler is unable to infer the type for the pricelist_item_id parameter. To resolve this issue, you can explicitly specify the type for this parameter. Here's the translated code with the relevant part:

export async function updatePricelistItem(
  pricelist_item_id: number, // Add the type here
  obj: UpdateConsumerT,
  isProduction: false
): Promise<number>

export async function updatePricelistItem(
  pricelist_item_id: number, // Add the type here
  obj: UpdateProducerT,
  isProduction: true
): Promise<number>

export async function updatePricelistItem(
  pricelist_item_id: number, // Add the type here
  obj,
  isProduction = false
) { ... }

By explicitly specifying the type for the pricelist_item_id parameter as number, you should resolve the TypeScript error.

英文:
type UpdateConsumerT = {
  obj: {
    min_quantity: number
    fixed_price: number
    date_start: string | boolean
    date_end: string | boolean
  }
}

type UpdateProducerT = {
  obj: {
    min_qty: number
    price: number
    date_start: string | boolean
    date_end: string | boolean
  }
}

export async function updatePricelistItem(
  pricelist_item_id: number,
  obj: UpdateConsumerT,
  isProduction: false
): Promise&lt;number&gt;
export async function updatePricelistItem(
  pricelist_item_id: number,
  obj: UpdateProducerT,
  isProduction: true
): Promise&lt;number&gt;
export async function updatePricelistItem(
  pricelist_item_id,
  obj,
  isProduction = false
) { ... }

I have this function, and i try to use overloads

But for some reason it says

> Parameter 'pricelist_item_id' implicitly has an 'any' type.ts(7006)

Typescript函数重载隐含地具有任何类型

My question is, what am i doing wrong here?

答案1

得分: 0

以下是您提供的代码的翻译:

您将需要在实现中明确指定参数类型和返回类型:

type UpdateConsumerT = {
  obj: {
    min_quantity: number
    fixed_price: number
    date_start: string | boolean
    date_end: string | boolean
  }
}

type UpdateProducerT = {
  obj: {
    min_qty: number
    price: number
    date_start: string | boolean
    date_end: string | boolean
  }
}

async function updatePricelistItem(
  pricelist_item_id: number,
  obj: UpdateConsumerT,
  isProduction: false
): Promise<number>
async function updatePricelistItem(
  pricelist_item_id: number,
  obj: UpdateProducerT,
  isProduction: true
): Promise<number>
async function updatePricelistItem(
  pricelist_item_id: number,
  obj: UpdateProducerT | UpdateConsumerT,
  isProduction = false
): Promise<number> { return new Promise(() => {}) }

Playground

英文:

You will need to explicitly specify the parameter types and return type on the implementation:

type UpdateConsumerT = {
  obj: {
    min_quantity: number
    fixed_price: number
    date_start: string | boolean
    date_end: string | boolean
  }
}

type UpdateProducerT = {
  obj: {
    min_qty: number
    price: number
    date_start: string | boolean
    date_end: string | boolean
  }
}

async function updatePricelistItem(
  pricelist_item_id: number,
  obj: UpdateConsumerT,
  isProduction: false
): Promise&lt;number&gt;
async function updatePricelistItem(
  pricelist_item_id: number,
  obj: UpdateProducerT,
  isProduction: true
): Promise&lt;number&gt;
async function updatePricelistItem(
  pricelist_item_id: number,
  obj: UpdateProducerT | UpdateConsumerT,
  isProduction = false
): Promise&lt;number&gt; { return new Promise(() =&gt; {}) }

Playground

答案2

得分: 0

函数重载实现当前无法从调用签名中上下文推断其参数类型。有一个长期存在的功能请求,可以在microsoft/TypeScript#25352中找到,但目前它不是语言的一部分。

在这个功能被实现之前,您需要手动注释函数实现的参数:

export async function updatePricelistItem(
  pricelist_item_id: number, // <-- 注释
  obj: UpdateConsumerT | UpdateProducerT, // <-- 注释
  isProduction = false // 从 false 推断为布尔值
) {
  return null!; // 抑制错误
}

请注意,因为您的调用签名对每个调用返回相同类型,所以您不需要使用重载。相反,您可以使用一个剩余参数,其类型是tuple types联合

export async function updatePricelistItem(
  pricelist_item_id: number,
  ...[obj, isProduction]:
    [obj: UpdateConsumerT, isProduction: false] |
    [obj: UpdateProducerT, isProduction: true]
): Promise<number> {
  return null!; // 抑制错误
}

declare const consumer: UpdateConsumerT;
declare const producer: UpdateProducerT;
updatePricelistItem(123, consumer, false); // 正常
updatePricelistItem(123, producer, true); // 正常
updatePricelistItem(123, consumer, true); // 错误

对于您的实现来说,这种方法更好,因为剩余参数是一个辨识联合isProduction 是辨识符,所以您可以在解构参数上使用控制流分析 来根据 isProduction 缩小 obj 的范围:

export async function updatePricelistItem(
  pricelist_item_id: number,
  ...[obj, isProduction]:
    [obj: UpdateConsumerT, isProduction: false] |
    [obj: UpdateProducerT, isProduction: true]
): Promise<number> {
  if (isProduction) {
    obj.obj.price // 正常,已知为 UpdateProducerT
  } else {
    obj.obj.fixed_price // 正常,已知为 UpdateConsumerT
  }
  return null!;
}

代码的Playground链接

英文:

Overload function implementations do not currently have their parameter types inferred contextually from the call signatures. There's a longstanding open feature request for this at microsoft/TypeScript#25352, but for now it's not part of the language.

Until and unless that gets implemented, you will need to manually annotate the function implementation's parameters:

export async function updatePricelistItem(
  pricelist_item_id: number,
  obj: UpdateConsumerT,
  isProduction: false
): Promise&lt;number&gt;
export async function updatePricelistItem(
  pricelist_item_id: number,
  obj: UpdateProducerT,
  isProduction: true
): Promise&lt;number&gt;

export async function updatePricelistItem(
  pricelist_item_id: number, // &lt;-- annotate
  obj: UpdateConsumerT | UpdateProducerT, // &lt;-- annotate
  isProduction = false // this is inferred as boolean from false
) {
  return null!; // suppress errors
}

Do note that because your call signatures return the same type for each call, you don't need to use overloads. Instead you can use a rest parameter whose type is a union of tuple types:

export async function updatePricelistItem(
  pricelist_item_id: number,
  ...[obj, isProduction]:
    [obj: UpdateConsumerT, isProduction: false] |
    [obj: UpdateProducerT, isProduction: true]
): Promise&lt;number&gt; {
  return null!; // suppress errors
}

declare const consumer: UpdateConsumerT;
declare const producer: UpdateProducerT;
updatePricelistItem(123, consumer, false); // okay
updatePricelistItem(123, producer, true); // okay
updatePricelistItem(123, consumer, true); // error

This approach is even better for your implementation because that rest parameter is a discriminated union with isProduction as the discriminant, so you can use control flow analysis on the destructured parameters to narrow obj based on isProduction:

export async function updatePricelistItem(
  pricelist_item_id: number,
  ...[obj, isProduction]:
    [obj: UpdateConsumerT, isProduction: false] |
    [obj: UpdateProducerT, isProduction: true]
): Promise&lt;number&gt; {
  if (isProduction) {
    obj.obj.price // okay, known to be UpdateProducerT
  } else {
    obj.obj.fixed_price // okay, known to be UpdateConsumerT
  }
  return null!;
}

Playground link to code

huangapple
  • 本文由 发表于 2023年7月6日 20:03:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76628626.html
匿名

发表评论

匿名网友

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

确定