假设我们需要实现一个返回值的方法,但是当该值是undefined
时,它应该返回一些传入的默认值。但是我们不想将默认值参数设为必需,因此将其声明为可选参数:
private returnSomething(someParam: string, defaultValue?: string) : string | undefined {
const result: string | undefined = ...; // Some result-producing logic
return result !== undefined ? result : defaultValue;
}
我们希望以下内容可以在严格模式下编译(注意,something1: string
类型声明为没有undefined
部分):
const something1: string = this.returnSomething("someParam1", "?"); // Error, no undefined in the type of something1
const something2: string | undefined = this.returnSomething("someParam2");
是否可以在TypeScript中声明一个方法,以便当不传递可选参数时,该方法的返回类型被视为string | undefined
,而在传递该参数时,返回类型变为string
?
答案 0 :(得分:2)
因此,如果我正确理解了您,只需使用generic类型,即可轻松实现:
const returnSomething = <D extends string | undefined>(someParam: string, defaultValue?: D) : D extends undefined ? string | undefined : string => {
const result = {} as any;
return result !== undefined ? result : defaultValue;
}
请参见playground
UPD以避免在不使用any
的情况下出错:
const returnSomething = <D extends string | undefined, R extends D extends undefined ? string | undefined : string>(someParam: string, defaultValue?: D) : R => {
const result = 'str';
return (result !== undefined ? result : defaultValue) as R;
}
UPD2。正确的方法(以及对此的歉意)。
我想道歉,因为在不必要的时候,我介绍了泛型和条件类型。我的意思是,我不知道它们会导致这样的错误。但是我也被最初的问题所误导。 因此,通常的方式,我将如何实现,像这样:
const returnSomething = (someParam: string, defaultValue?: string): string | undefined => {
const result = '';
return result !== undefined ? result : defaultValue;
}
const something1 = returnSomething("someParam1", "?");
const something2 = returnSomething("someParam2");
就是这样。是的,您不应该为something1
和something2
分配类型。相反,您应该进行运行时检查(并且打字稿从检查中推断出类型):
if (typeof something1 === 'undefined') {
/* oops the value is undefined, do something to make the program continue working properly */
}
else {
something1 // has type "string"
}
关于错误,我已经提交了issue。
答案 1 :(得分:1)
Nurbol是其中的大部分方式,我必须进行另一处更改才能使其完全正常工作:
const returnSomething = <D extends string | undefined>(someParam: string, defaultValue?: D) : D extends undefined ? string | undefined : string => {
const result = {} as any;
return result !== undefined ? result : defaultValue;
}
const something1: string = returnSomething("someParam1", "d"); // No error
const something2: string | undefined = returnSomething("someParam2"); // No error
const something3: string = returnSomething("someParam2"); // Yes error
const something4: string = returnSomething("someParam2", undefined); // Yes error
我们需要定义D
以便最初接受undefined
,否则条件将始终仅返回string
。
尽管这样做的副作用是现在允许您将undefined
作为默认值进行传递。仍然会出现预期的错误。
您也可以通过函数重载来做到这一点:
function returnSomething(param: string): string | undefined;
function returnSomething(param: string, defaultValue: string): string;
function returnSomething(param: string, defaultValue?: string) {
const result = {} as any;
return result !== undefined ? result: defaultValue;
}
这避免了undefined
问题。