首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法传递类型解析为不同重载的联合类型。

无法传递类型解析为不同重载的联合类型。
EN

Stack Overflow用户
提问于 2018-10-04 15:15:34
回答 1查看 336关注 0票数 0

作为参考,我正在尝试解析定义类型/定义类型#29312

下面的代码会导致错误,但不应该。

代码语言:javascript
复制
declare const $: JQueryStatic;

let value: string | HTMLElement = {} as any;
$(value);
代码语言:javascript
复制
Argument of type 'string | HTMLElement' is not assignable to parameter of type 'PlainObject<any>'.
  Type 'string' is not assignable to type 'PlainObject<any>'.

JQueryStatic的调用签名当前定义为:

代码语言:javascript
复制
interface JQueryStatic {
    <TElement extends HTMLElement = HTMLElement>(html: string, ownerDocument_attributes?: Document | JQuery.PlainObject): JQuery<TElement>;
    <TElement extends Element = HTMLElement>(selector: string, context?: Element | Document | JQuery): JQuery<TElement>;
    <T extends Element>(element: T): JQuery<T>;
    <T extends Element>(elementArray: T[]): JQuery<T>;
    <T>(selection: JQuery<T>): JQuery<T>;
    <TElement = HTMLElement>(callback: ((this: Document, $: JQueryStatic) => void)): JQuery<TElement>;
    <T extends JQuery.PlainObject>(object: T): JQuery<T>;
    <TElement = HTMLElement>(): JQuery<TElement>;
}

interface JQuery<T = HTMLElement> {
    jquery: string;
}

declare namespace JQuery {
    type PlainObject<T = any> = { [name: string]: T; };
}

stringHTMLElement有单独的重载,它们可以与之匹配,但不能作为一个联合。这个场景中的解决方案是统一签名。我尝试了以下几点:

代码语言:javascript
复制
interface JQueryStatic2 {
    // This solution doesn't entirely fulfill the original requirements but
    // seems like a good starting point.
    <TElement extends HTMLElement = never,
        JElement = never,
        T extends JQuery.PlainObject = never>(
        arg: string |
            TElement |
            TElement[] |
            JQuery<JElement> |
            ((this: Document, $: JQueryStatic) => void) |
            T
    ): JQuery<TElement | JElement | T>;
}
代码语言:javascript
复制
Argument of type 'string | HTMLElement' is not assignable to parameter of type 'string | ((this: Document, $: JQueryStatic) => void) | JQuery<never> | never[]'.
  Type 'HTMLElement' is not assignable to type 'string | ((this: Document, $: JQueryStatic) => void) | JQuery<never> | never[]'.
    Type 'HTMLElement' is not assignable to type 'never[]'.
      Property 'length' is missing in type 'HTMLElement'.

我希望这与TElement = HTMLElementJElement = neverT = never相匹配。相反,TElement | T似乎被从工会中淘汰了。

我猜想这可以用条件类型来解决,但是@types/jquery目前的目标是TypeScript 2.3,所以我更喜欢不使用新特性来保持兼容性的解决方案。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-10-14 13:57:30

我求助于使用条件类型(需要TypeScript 2.8)。

代码语言:javascript
复制
interface JQueryStatic {
    <TDeclared = JQuery._Unknown,
    T extends string | Element[] | JQuery<any> | Element | JQuery.PlainObject =
              string | Element[] | JQuery<any> | Element | JQuery.PlainObject,
    TReturn =
        TDeclared extends JQuery._Unknown ?
            T extends string ? HTMLElement :
            T extends Element[] | JQuery<any> ? T[number] :
            T extends Element | JQuery.PlainObject ? T :
            never :
        TDeclared>(html_selector_element_elementArray_object_selection: T): JQuery<TReturn>;
}

namespace JQuery {
    interface _Unknown {
        __unknown: never;
    }
}

这统一了许多原始签名,但却使现在的TDeclared不再受约束。T表示参数的类型,并受限于原始签名的可能类型。如果声明了TReturn (即与哨兵类型JQuery._Unknown不兼容),则它等于TDeclared,否则,将根据T类型推断它。由于T的声明方式,never分支应该是不可访问的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52650182

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档