簡體   English   中英

可以根據類型參數覆蓋的打字稿類型

[英]Typescript types that can be overwritten based on type arguments

我試圖找出告訴打字稿編譯器返回T | null的函數的最佳方法。 在某些情況下, T | null肯定是T

也許我正在考慮這個錯誤,在這種情況下我也對新想法持開放態度,這里是片段:

type ValueOrNull<T, N> = N extends false ? T | null : T;

export function getCookie<T = any, N = false>(name: string): ValueOrNull<T, N> {
  const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));

  if (match) {
    const [, , value] = match;

    return parseCookieValue(value) as T;
  }

  return null;
}

我的想法是,如果我可以按如下方式調用該函數: getCookie<TMyCookie, true>("my_cookie")打字稿會知道我確定 cookie 會在那里,並且該函數不會返回 null。 例如成功登錄后。

N extends false ? 感覺不對,但N === false不起作用。

編譯器錯誤是Type 'null' is not assignable to type 'ValueOrNull<T, N>'.ts(2322)

非常感謝

您可以通過函數重載和第二個參數輕松地做到這一點; 當(不可避免地)程序員“知道”cookie存在但它不存在時,這也可以讓您構建一個有用的解釋性錯誤:

export function getCookie<T>(name: string, required: true): T;
export function getCookie<T>(name: string, required?: false): T | null;
export function getCookie<T>(name: string, required?: boolean): T | null {
    const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));

    if (match) {
        const [, , value] = match;
        // You'll want to put your `parseCookingvalue` back here,
        // the `as any as T` is just because we don't have that
        // function available to use in the question.
        return /*parseCookieValue(value)*/ value as any as T;
    } else if (required) {
        throw new Error(`Required cookie "${name}" was not found`);
    }
    return null;
}

const a = getCookie<string>("a", true);
//    ^? −−−− type is string
const b = getCookie<string>("b", false);
//    ^? −−−− type is string | null

游樂場鏈接


不過,這里有一個替代方案:您可以讓getCookie相當簡單,並擁有一個通用類型斷言函數,您可以在任何地方使用該函數,您可以返回可能為nullundefined並且您“知道”它不是nullundefined的東西:

export function getCookie<T>(name: string): T | null {
    const match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));

    if (match) {
        const [, , value] = match;
        // You'll want to put your `parseCookingvalue` back here,
        // the `as any as T` is just because we don't have that
        // function available to use in the question.
        return /*parseCookieValue(value)*/ value as any as T;
    }
    return null;
}

export function assertIsNotNullish<T>(value: T | null | undefined): asserts value is T {
    if (value == null) {
        throw new Error(`Expected non-nullish value, got ${value}`);
    }
}

const a = getCookie<string>("a");
assertIsNotNullish(a);
console.log(a);
//          ^? −−−− type is string
const b = getCookie<string>("b");
console.log(b);
//          ^? −−−− type is string | null

游樂場鏈接

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM