接口属性共享相同的泛型类型

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

Interface properties to share the same same generic type

问题

我正试图做与这里的问题类似的事情。我想要扩展Argument类型,其中有几个共享相同类型的方法:

type ArgumentType = "string" | "number"

type Argument = {
  type: ArgumentType;
  d?: () => ArgumentTypeI
  s?: (v: ArgumentTypeI | undefined) => ArgumentTypeI[] 
}

其中ArgumentTypeITypeMap中定义的ArgumentType类型的实际实例。

要修改@wonderflame提供的示例以支持我的上述示例,需要做什么修改?

编辑:

我已经更新了示例,展示了我想要实现的内容

英文:

I'm trying to do something similar as in the question here. I want to extend Argument with a couple of methods that all share the same type:

type ArgumentType = "string" | "number"

type Argument = {
  type: ArgumentType;
  d?: () => ArgumentTypeI
  s?: (v: ArgumentTypeI | undefined) => ArgumentTypeI[] 
}

where ArgumentTypeI is an actual instance of ArgumentType type defined in TypeMap

What to modify in the the example given by @wonderflame to support my example above?

EDIT:

I've updated the example with what I would like to achieve here

答案1

得分: 1

这是您提供的代码的翻译部分:

我不确定为什么,但编译器无法正确推断[辨别联合](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions)的类型,只有在类型定义为具有联合值的单个对象时才能正常工作:

```typescript
type Argument = {
  type: keyof TypeMap;
  default?: () => TypeMap[keyof TypeMap];
};

通过这样做,我们将修复default函数的返回类型,以正确的类型返回。然而,现在我们不是类型安全的,因为我们可以返回number,而类型是string,我能够得到的最接近的方法是在类型中检查返回类型是否与TypeMap中的类型相同:

interface Command<
  T extends Record<string, Argument> = Record<string, Argument>,
> {
  label: string;
  arguments: { [K in keyof T]: ReturnType<NonNullable<T[K]['default']>> extends TypeMap[T[K]['type']] ? T[K] : never }
  handler: (options: HandlerOptions<T>) => void;
}

请注意,我们使用NonNullable,因为default是可选的,我们使用ReturnType来获取返回值并检查它是否与TypeMap中的类型相同。如果类型正确,我们不对值进行任何操作,否则,我们将值分配为never,这将引发错误。

播放链接


希望这有助于您理解代码的翻译部分。如果您有其他问题,请随时提出。

<details>
<summary>英文:</summary>

I&#39;m not sure why exactly, but the compiler can&#39;t infer types correctly with [discriminated unions](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions) and works only if the type is defined as single object with union values:

type Argument = {
type: keyof TypeMap;
default?: () => TypeMap[keyof TypeMap];
};


By doing this we will fix the return type of the `default` function to the correct type, however, now we are not type-safe since we can return `number` where the type is `string` and the closest that I could get is to check in the type whether the return type is same as the type from `TypeMap`:

interface Command<
T extends Record<string, Argument> = Record<string, Argument>,
> {
label: string;
arguments: { [K in keyof T]: ReturnType<NonNullable<T[K]['default']>> extends TypeMap[T[K]['type']] ? T[K] : never }
handler: (options: HandlerOptions<T>) => void;
}


Note that we use [NonNullable](https://www.typescriptlang.org/docs/handbook/utility-types.html#nonnullabletype), since `default` is optional and we use [ReturnType](https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype) to get the return value an check if it is the same as it is in the `TypeMap`. If the type is correct we don&#39;t do anything to the values, otherwise, we assign the value to `never`, which will raise the error.

[Link to Playground](https://www.typescriptlang.org/play?ts=5.0.4#code/C4TwDgpgBAKuEFkCGYoF4oG8BQUoGdgAnASwDsBzALgOPIoG5coyBXAWwCMIia2ueTAL5Ns2UJCgBBIhQ4QywdFmYSINANYQQAewBmseMjBM8AEwh6krADbAA-DQAUASnQA+Q5GMBtLboM4bxQAXWFRNSgABSIIYGASPRAAHhhPDBgoCAAPYAUzfChyPR4oACUoeywoHwBpIrIof31ykJoyupCoISg+CAA3QTFIgAkkMjMbHgB5MASdMnxUrNz8wrKIAGMdIjNkwlJKABppWXlFd3To2PjElJw8Ooam7RaYNq9EFB8YTp8AcjU-xCYWwQnconIeSIVk20AAwjp2OxxntmJkcnkJustjs9gd6CcZHJ2ApgFcNttdvs6MdTiSye4jthPA8oDYkNwbDQCZRTFAkGdSYp8DRMDV6uQXgFYB8NsBWEQyEEIMkAHILNW2DmcKapP7-CxWWzAYGXFZYgqfXy-WohAFAkGVWCdXosAalITMAAWqKmvCgTh0cxIC1FUDGE39s3mi1S7jcaE8-R0JDMwjE2G2iyUFDiiORqOUyWzhFgFrW5Vx1N5FCJQsZ7ic20LExoBZRE3jifczBbnfTYlLSk27DMyjzwA7qKcbJ1EG5UH+OS2rDyAFpgEh8Bp-sy8IKGSKxcw8FudwB9MhIUknvD3qBqGj-Wt70-3o3WOzOHsqB8Pm5FUaAB2YD+QfIR93vSD33PDQrxvCAACY73-J8l1fKCH0-E0fw8P9-zwQClSXUD-nA6CsO6ZlmBgvBfSjHggxDMM3DZPBg1jfAKIAeh4qAAD17Fo5khBcURhygHC7AANSQGxWGgDBRzMAA6Q9zmAfBVLghDSSQ1TpOAVwGCgPioHYVgy24WhDgobAgA)

</details>



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

发表评论

匿名网友

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

确定