英文:
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[]
}
其中ArgumentTypeI
是TypeMap
中定义的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'm not sure why exactly, but the compiler can'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'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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论