函数重载中的返回类型不正确,TypeScript中没有函数参数



我有一个函数,它可以根据特定条件返回具有不同值的对象。此函数不接收任何参数。

我写了两个重载,描述了不同的返回类型,但当我使用这个函数并试图从对象中析取值时,我总是会收到第一个重载中定义的值,即使它不符合条件。

代码段:

const params = {
brandId: 1, // could be undefined
productId: 2, // could be undefined
centerId: 3, // could be undefined
};
type ValidParams = {
isValid: boolean;
params: {
brandId: number;
productId: number;
centerId: number;
};
};
type InvalidParams = {
isValid: boolean;
params: {
brandId: undefined;
productId: undefined;
centerId: undefined;
};
};
export function useParams(): ValidParams;
export function useParams(): InvalidParams;
export function useParams() {
const { brandId, productId, centerId } = params;
if (brandId && productId && centerId) {
return {
isValid: true,
params: {
brandId,
productId,
centerId,
},
};
} else {
return {
isValid: false,
params: {
brandId: undefined,
productId: undefined,
centerId: undefined,
},
};
}
}
function someFunction() {
const {
isValid,
params: { brandId, productId, centerId },
} = useParams();
if (isValid) {
const id = brandId;
}
}

我预计,如果isValid的值为true,那么所有的参数都是数字,而如果isValid为false,那么参数是未定义的。

例如:

if (isValid) {
brandId, productId, centerId // all are numbers
}

TS游乐场链接

TS版本:4.6.3

非常感谢在这方面的任何帮助(

您可以将params对象作为参数传递给useParams函数。这样你就有了一些要重载的参数。

同时使isValid成为两个接口的文字类型

类似这样的东西:

const params = {
brandId: undefined, // could be undefined
productId: undefined, // could be undefined
centerId: undefined, // could be undefined
};
type ValidParams = {
isValid: true;
params: {
brandId: number;
productId: number;
centerId: number;
};
};
type InvalidParams = {
isValid: false;
params: {
brandId: undefined;
productId: undefined;
centerId: undefined;
};
};
// accept params as an argument so that you have some parameters to overload
export function useParams(_params: {
brandId: undefined;
productId: undefined;
centerId: undefined;
}): InvalidParams;
export function useParams(_params: {
brandId: number;
productId: number;
centerId: number;
}): ValidParams;
export function useParams(_params: {
brandId: number | undefined;
productId: number | undefined;
centerId: number | undefined;
}) {
const { brandId, productId, centerId } = _params;
if (brandId && productId && centerId) {
return {
isValid: true,
params: {
brandId,
productId,
centerId,
},
};
} else {
return {
isValid: false,
params: {
brandId: undefined,
productId: undefined,
centerId: undefined,
},
};
}
}
const {
isValid,
params: { brandId, productId, centerId },
} = useParams(params); // pass params as an argument
if (isValid && brandId && productId && centerId) {
const id: number = brandId;
}

在这种情况下,我相信您不需要isValid标志,所以您可以按如下方式删除它。

const params = {
brandId: 1, // could be 1
productId: 1, // could be 1
centerId: 1, // could be 1
};
type ValidParams = {
params: {
brandId: number;
productId: number;
centerId: number;
};
};
type InvalidParams = {
params: {
brandId: undefined;
productId: undefined;
centerId: undefined;
};
};
// accept params as an argument so that you have some parameters to overload
export function useParams(_params: {
brandId: undefined;
productId: undefined;
centerId: undefined;
}): InvalidParams;
export function useParams(_params: {
brandId: number;
productId: number;
centerId: number;
}): ValidParams;
export function useParams(_params: {
brandId: number | undefined;
productId: number | undefined;
centerId: number | undefined;
}) {
const { brandId, productId, centerId } = _params;
if (brandId && productId && centerId) {
return {
params: {
brandId,
productId,
centerId,
},
};
} else {
return {
params: {
brandId: undefined,
productId: undefined,
centerId: undefined,
},
};
}
}
const {
params: { brandId, productId, centerId },
} = useParams(params); // pass params as an argument
if (brandId && productId && centerId) {
const id: number = brandId;
}

它仍然是一个有效的代码。如果将{brandId: 1, productId: 1, centerId: 1}作为参数传递给useParams,则会将brandId && productId && centerId作为true,因为重载会将所有类型推断为number类型。对于CCD_ 11型也是如此。

这仍然是一个有效的代码。如果将{brandId: 1, productId: 1, centerId: 1}作为参数传递给useParams,则会将brandId && productId && centerId作为true,因为溢出会将每个类型推断为"数字"类型。这同样适用于undefined类型。

处理这一问题的一个简单方法是以不同的方式定义返回类型,并指示函数可以返回一个或另一个带有判别并集的返回类型。

在这段代码中,在编译器允许您访问值之前,需要测试isValid是否为true。我还调整了测试以明确检查CCD_ 19,因为CCD_;不在那里";。您可以保留";truthy数字;检查0是否不是有效值,但您明确指出它可能是未定义的,而不指示0也是无效的。

const params = {
brandId: 1, // could be undefined
productId: 2, // could be undefined
centerId: undefined, // could be undefined
};
type ValidParams = {
isValid: true;
params: {
brandId: number;
productId: number;
centerId: number;
};
};
type InvalidParams = {
isValid: false;
};
function useParams(): ValidParams | InvalidParams {
const { brandId, productId, centerId } = params;
if (brandId != undefined && productId != undefined && centerId != undefined) {
return {
isValid: true,
params: {
brandId,
productId,
centerId,
},
};
} else {
return {
isValid: false,
};
}
}
function someFunction() {
// cannot destructure the params here, because we don't
// know yet if it is valid or invalid type
const p = useParams();
if (p.isValid) {
// we know now we have the params values,
// so we can access, destructure, etc.
const id = p.params.brandId;
}
console.dir(p);
}
someFunction();

TypeScript游乐场

最新更新