打字稿声明:T | null | undefined返回您传入的类型

时间:2017-01-12 02:52:09

标签: typescript

我试图改进a function in angular的DefinitelyTyped定义。它目前看起来像这样:

<T>(array: T[], a_bunch_more_stuff): T[];

使用strictNullChecks这不允许传入,例如T[]|undefined。我检查了角度来源,它专门检查并允许nullundefined。在这些情况下,它只返回第一个参数。这是我能想到更新.d.ts文件的最佳方式:

<T>(array: T[], a_bunch_more_stuff): T[];
<T>(array: T[]|null, a_bunch_more_stuff): T[]|null;
<T>(array: T[]|undefined, a_bunch_more_stuff): T[]|undefined;
<T>(array: T[]|null|undefined, a_bunch_more_stuff): T[]|null|undefined;

这将在返回值上保留正确的联合。例如,如果我们只使用了最后一行并且传入了T[]|null,则返回值将为T[]|null|undefined,这太宽了。是否有一种更简洁的方式来表达这四条线,同时保持其良好的行为?

1 个答案:

答案 0 :(得分:1)

是的,您可以声明函数返回与其第一个参数完全相同的类型,并使用两个通用参数表达对参数类型的约束,如下所示:

function x<T, Q extends T[] | null | undefined>(a: Q, ...args: any[]): Q {
    return a;
}

class C {

    a1: string[];

    a2: string[] | null;

    a3: string[] | undefined;

    a4: string[] | null | undefined;

    f() {

        // check all permutations

        this.a1 = x(this.a1);
        this.a2 = x(this.a2);
        this.a3 = x(this.a3);
        this.a4 = x(this.a4);

        this.a1 = x(this.a2);  // disallowed
        this.a1 = x(this.a3);  // disallowed
        this.a1 = x(this.a4);  // disallowed

        this.a2 = x(this.a1);
        this.a2 = x(this.a3);  // disallowed
        this.a2 = x(this.a4);  // disallowed

        this.a3 = x(this.a1);
        this.a3 = x(this.a2);  // disallowed
        this.a3 = x(this.a4);  // disallowed

        this.a4 = x(this.a1);
        this.a4 = x(this.a2);
        this.a4 = x(this.a3);
        this.a4 = x(this.a4);
    }
}

请注意,对于strictNullChecks,这会使T[] | undefinedT[] | null不兼容,而using OpenQA.Selenium; using OpenQA.Selenium.Chrome; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace SeleniumThree { class Program { static void Main(string[] args) { IWebDriver driver = new ChromeDriver(); driver.Navigate().GoToUrl("www.facebook.com"); driver.Manage().Window.Maximize(); IWebElement Username = driver.FindElement(By.Name("FORMLOGINid")); Username.SendKeys("UserName"); Thread.Sleep(1000); IWebElement Password = driver.FindElement(By.Name("FORMLOGINpwd")); Password.SendKeys("Password"); Thread.Sleep(1000); IWebElement LoginButton = driver.FindElement(By.Name("btSubmit")); LoginButton.Click(); Thread.Sleep(3000); try { IWebElement MenuArrow = driver.FindElement(By.XPath(@"//*[@id='id_arrow_popup_menu']/img")); MenuArrow.Click(); Thread.Sleep(1000); } catch (Exception e) { Console.WriteLine("{0} Exception caught.", e); } } } } 对于实际代码可能过于严格。