簡體   English   中英

根據可選參數指定返回類型

[英]Specifying the return type based on optional parameters

function f<T>(defaultValue?: T) { return defaultValue; }

const definitelyUndefined = f<string>();      // type: string | undefined
const definitelyString = f<string>('foobar'); // type: string | undefined

是否有可能定義f()使得definitelyUndefined是隱式undefineddefinitelyString是隱式string

背景

我的真實用例是我正在使用並希望改進的功能。 它是function f<T>(o: { [key: string]: T }, key: string, defaultValue?: T)並且如果存在則返回key[o] ,否則defaultValue 當我提供一個defaultValue ,我保證會得到T ,但 Typescript 認為它T | undefined T | undefined

對於您的第一種情況,我立即想到使用重載,例如:

function f<T>(): undefined;
function f<T>(value: T): T;
function f<T>(value?: T) { return value; }

const definitelyUndefined = f();      // type: undefined
const definitelyString = f('foobar'); // type: "foobar"

但是,對於更復雜的用例,我認為您可以使用重載和更復雜的泛型來解決它,例如:

function f<T, K extends string & keyof T>(o: T, key: K, defaultValue?: T[K]): T[K];
function f<T, V = undefined>(o: T, key: string, defaultValue?: V): V;
function f<T, V = undefined>(o: T, key: string, defaultValue?: V) {
  return o[key] || defaultValue;
}

const obj = { foo: "123" };

const definitelyUndefined = f(obj, "bar");    // type: undefined
const definitelyNumber = f(obj, "bar", 123);  // type: number
const definitelyString = f(obj, "foo");       // type: string

我不知道這是否適用於所有可能的場景(因為返回類型是基於泛型類型參數確定的,而不是實際的函數參數),但我認為它非常接近。

遺憾的是,除了重載之外,沒有一流的支持。
這是我遲來的貢獻。

// Type definition
type ValueOrUndefined<T> =
  T extends (string | number | boolean | symbol | object) ? T : undefined;

// Function definition
function f<T>(defaultValue?: T): ValueOrUndefined<typeof defaultValue> {
  return defaultValue as any;
}

// Invocations
const definitelyUndefined = f();      // type: undefined
const definitelyString = f('foobar'); // type: string

這種方法的優點是在指定重載並不總是方便的界面中對我們更方便( https://github.com/microsoft/TypeScript/issues/7230 )但您必須謹慎,因為它不是完全類型 -如果開發人員調用函數決定顯式提供泛型類型,則安全:

const wronglyTyped = f<string>();      // type: string

雖然沒有開發人員有理由在這個簡單的例子上做這樣的事情,但在具體情況下,他們可能需要這樣做,特別是如果類型 T 用於其他參數或實際函數具有其他泛型參數。

暫無
暫無

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

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