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

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

Interface properties to share the same same generic type

问题

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

  1. type ArgumentType = "string" | "number"
  2. type Argument = {
  3. type: ArgumentType;
  4. d?: () => ArgumentTypeI
  5. s?: (v: ArgumentTypeI | undefined) => ArgumentTypeI[]
  6. }

其中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:

  1. type ArgumentType = "string" | "number"
  2. type Argument = {
  3. type: ArgumentType;
  4. d?: () => ArgumentTypeI
  5. s?: (v: ArgumentTypeI | undefined) => ArgumentTypeI[]
  6. }

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

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

  1. 我不确定为什么,但编译器无法正确推断[辨别联合](https://www.typescriptlang.org/docs/handbook/2/narrowing.html#discriminated-unions)的类型,只有在类型定义为具有联合值的单个对象时才能正常工作:
  2. ```typescript
  3. type Argument = {
  4. type: keyof TypeMap;
  5. default?: () => TypeMap[keyof TypeMap];
  6. };

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

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

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

播放链接

  1. 希望这有助于您理解代码的翻译部分。如果您有其他问题,请随时提出。
  2. <details>
  3. <summary>英文:</summary>
  4. 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];
};

  1. 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;
}

  1. 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.
  2. [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)
  3. </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:

确定