我正试图创建一个函数,该函数仅在参数包含返回值的情况下,才将string
包含在number
中并返回undefined
。
这就是我所拥有的(我认为可以使用):
export function test<T extends string | undefined>(a: T)
:Exclude<boolean | T, string> {
if (a === undefined)
return undefined;
return true;
}
我希望Exclude<boolean | T, string>
从string
中删除string | undefined
,而使undefined
或什么都不留(取决于所提供的参数类型),但是该代码不会键入-检查,上面写着:
类型
'undefined'
不可分配给类型'boolean | Exclude<T, string>'
。
答案 0 :(得分:4)
无法解析的条件类型(例如Exclude<boolean | T, string>
和T
泛型)通常不是可分配的。编译器实际上并不知道如何确定某物是否属于此类,因为它不会尝试遍历泛型T
的所有可能实例以查看分配是否安全。因此,在这些情况下,通常assert就是那个类型的值,或者您使用function overloads以便函数实现使用普通的联合类型而不是条件类型。这是断言解决方案:
export function test<T extends string | undefined>(a: T): Exclude<boolean | T, string> {
if (a === undefined)
return undefined as Exclude<boolean | T, string>; // asserted
return true;
}
这是过载解决方案:
export function test<T extends string | undefined>(a: T): Exclude<boolean | T, string>;
// overloaded
export function test(a: string | undefined): boolean | undefined {
if (a === undefined)
return undefined;
return true;
}
只要在使用具体类型的值调用它们时,只要它们按照您希望的方式工作,那么条件类型就应该表现出您所期望的:
const definitelyDefined = test("hey"); // boolean, okay
const maybeUndefined = test(Math.random()<0.5 ? "hey" : undefined); // boolean | undefined, okay
(顺便说一句,我可能会将您的返回类型呈现为boolean | (undefined extends T ? undefined : never)
:
export function test<T extends string | undefined>(
a: T
): boolean | (undefined extends T ? undefined : never) {
if (a === undefined)
return undefined as (undefined extends T ? undefined : never); // asserted
return true;
}
但这只是优先事项。
好的,希望能有所帮助;祝你好运!
答案 1 :(得分:1)
您可以使用function overloads来实现。首先,使函数接受任一类型并返回任一种类型,然后添加重载定义以限制可以一起使用的参数和返回类型。
function test(a: string): boolean;
function test(a: undefined): undefined;
function test(a: string | undefined): boolean | undefined {
if (a === undefined)
return undefined;
return true;
}