Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 完全扩展联合类型_Typescript - Fatal编程技术网

Typescript 完全扩展联合类型

Typescript 完全扩展联合类型,typescript,Typescript,假设以下示例代码: type Action = "GET" | "POST" | "PUT"; type Handler<A extends Action> = (action: A) => void; const handlers: Partial<Record<Action, Handler<Action>>> = { }; function register<A extends Action>(action: A, ha

假设以下示例代码:

type Action = "GET" | "POST" | "PUT";
type Handler<A extends Action> = (action: A) => void;

const handlers: Partial<Record<Action, Handler<Action>>> = { };

function register<A extends Action>(action: A, handler: Handler<A>) {
    /*
    Error:
    Type 'Handler<A>' is not assignable to type 'Partial<Record<Action, Handler<Action>>>[A]'.
        Type 'Handler<A>' is not assignable to type 'Handler<Action>'.
            Type 'Action' is not assignable to type 'A'.
            'Action' is assignable to the constraint of type 'A', but 'A' could be instantiated with a different subtype of constraint 'Action'.
                Type '"GET"' is not assignable to type 'A'.
                '"GET"' is assignable to the constraint of type 'A', but 'A' could be instantiated with a different subtype of constraint 'Action'.
     */
    handlers[action] = handler;
}

其中return语句给出与上述相同的错误。这揭示了实际的问题:
T
实际上可能比union小,因此您可能最终传入的函数处理的情况比预期的要少。

一个好的解决方案将不存在,除非实现或强制转换它


扩展操作
不允许
A
操作
大。它不能是
操作|“删除”
A扩展了B
意味着
A
B
的一个子类型,或者如果您有
A
类型的值,那么它也必须是
B
类型。
Action |“DELETE”
类型的值不一定是
Action
类型的值,因为它可能是
“DELETE”


您可能希望将
handlers
定义为将键与值关联的映射类型:
const handlers:{[K in Action]?:Handler}={}


但是问题仍然存在,编译器无法看到
处理程序[action]
处理程序
是兼容的,原因如上面第一句所述。TypeScript中没有对类型的强大支持,而且这只会变得更糟,因为TS3.5通过索引访问获得了更多。一个好的解决方案将不存在,除非或者实现了,所以只需将它转换为
A extensed Action
就不允许
A
Action
大。它不能是
操作|“DELETE”
A扩展了B`意味着
A
B
的子类型,或者如果您有
A
类型的值,那么它也必须是
B
类型。类型为
Action |“DELETE”
的值不一定是
Action
类型的值,因为它可能是
“DELETE”
。您可能希望将
handlers
定义为将键与值关联的映射类型:
const handlers:{[K in Action]?:Handler}={}
但问题仍然存在,编译器无法看到
处理程序[操作]
处理程序
是兼容的,原因是@Austraas提到的。TypeScript中对类型的支持不是很好,而且这只会变得更糟,因为TS3.5在索引访问方面得到了更多的支持。看看它试图完全解释这种消息的含义。让我知道它是否解决了你的问题。这是一个上传到问题下的上传评论的拷贝和粘贴。我在这里转发这些评论作为答案,以防这些评论被删除。
function foobar<T extends "foo" | "bar">(func: (arg: T) => void): (arg: "foo" | "bar") => void {
    return func;
}