Typescript TypeCScript具有未知的条件类型

Typescript TypeCScript具有未知的条件类型,typescript,typescript-typings,conditional-types,Typescript,Typescript Typings,Conditional Types,我试图正确键入以下函数: function nullToUndefined(p: null): undefined; function nullToUndefined<T extends Exclude<unknown, null>>(p: T): T; function nullToUndefined<T extends Exclude<unknown, null>>(p: null | T): T | undefined { retur

我试图正确键入以下函数:

function nullToUndefined(p: null): undefined;
function nullToUndefined<T extends Exclude<unknown, null>>(p: T): T;
function nullToUndefined<T extends Exclude<unknown, null>>(p: null | T): T | undefined
{
    return p === null ? undefined : p; 
}
但是,它不适用于下面的代码

const d = nullToUndefined(1 as number | null);
变量d的类型是
number | null
,但我希望看到
number |
未定义
。问题似乎出在
T extends Exclude
-因为unknown是所有类型的超类型,我希望T是除null之外的所有类型,但显然它不是这样工作的

比如我能做什么

const e: Exclude<unknown, null> = null;
const e:Exclude=null;
TS编译器也没有抱怨


这是预期的行为,还是我以错误的方式使用unknown?有没有其他方法可以实现函数的正确键入?

您需要使用自己的条件类型将
null
类型映射到
未定义的
类型。由于在union类型的每个成员上都执行条件,因此代码非常简单。唯一需要注意的是,如果指定函数的返回类型为条件,则必须强制转换实际值:

type NullToUndefined<T> = T extends null ? undefined : T

function nullToUndefined<T>(p: T): NullToUndefined<T>
{
    return (p === null ? undefined : p) as NullToUndefined<T>; 
}

const d1 = nullToUndefined(null); // undefined
const d2 = nullToUndefined(1 as number | null); // number | undefined
type NullToUndefined=T扩展空值?未定义:T
函数nullToUndefined(p:T):nullToUndefined
{
返回(p==null?未定义:p)为NullToUndefined;
}
常数d1=nullToUndefined(null);//未定义
常数d2=nullToUndefined(1作为数字| null);//编号|未定义

您需要使用自己的条件类型将
null
类型映射到
未定义的
类型,而不是使用
排除
。由于在union类型的每个成员上都执行条件,因此代码非常简单。唯一需要注意的是,如果指定函数的返回类型为条件,则必须强制转换实际值:

type NullToUndefined<T> = T extends null ? undefined : T

function nullToUndefined<T>(p: T): NullToUndefined<T>
{
    return (p === null ? undefined : p) as NullToUndefined<T>; 
}

const d1 = nullToUndefined(null); // undefined
const d2 = nullToUndefined(1 as number | null); // number | undefined
type NullToUndefined=T扩展空值?未定义:T
函数nullToUndefined(p:T):nullToUndefined
{
返回(p==null?未定义:p)为NullToUndefined;
}
常数d1=nullToUndefined(null);//未定义
常数d2=nullToUndefined(1作为数字| null);//编号|未定义