【发布时间】:2019-02-02 04:02:47
【问题描述】:
我需要帮助说服 Typescript 推断用户输入的字符串文字,而不是使用具有所有可能值的字符串。
看看这个例子 (playground link):
// Supported methods.
type Methods = "GET" | "PUT" /* and etc. */;
// Event interface for each method.
interface Events {
[key: string]: [any, any];
}
// Event objects assigned to methods.
type MethodicalEvents = {
[key in Methods]: Events | undefined;
};
// Extract string keys only.
type EventKeys<E extends Events> = Extract<keyof E, string>;
// Extract all event keys from `MethodicalEvents -> Events`.
type AllEvents<O extends MethodicalEvents, M extends Methods> =
O[M] extends object ? EventKeys<O[M]> : never;
// Extract send value (first array value in `Events` interface).
type ExtractSendValue<O extends MethodicalEvents, M extends Methods, E extends AllEvents<O, M>> =
O[M] extends object ?
O[M][E] extends [any, any] ?
O[M][E][0] :
never :
never;
// Interface implementing stuff from above.
interface Foo extends MethodicalEvents {
PUT: {
"1": [123, void];
"2": [string, void];
"3": [boolean, void];
};
}
// Class for making requests via `Foo` interface.
class Bar<O extends MethodicalEvents> {
public request<M extends Methods, E extends AllEvents<O, M>>(
method: M,
event: E,
data: ExtractSendValue<O, M, E>,
) {
// Do stuff...
}
}
const bar = new Bar<Foo>();
// `true` should not be allowed.
bar.request("PUT", "1", true /*type: `string | boolean | 123`*/);
// type is `123`, as expected
type ExpectedType = ExtractSendValue<Foo, "PUT", "1">;
bar.request 的第二个参数的类型为 "1" | "2" | "3",而我希望它具有 "1" 作为类型。
我怎样才能做到这一点?
【问题讨论】:
-
我认为这是一个错误,你可以在 GitHub 上提交。
-
谢谢,您的解决方案确实有效,我将在 Github 上打开一个问题。
标签: typescript