typescript - How to type a function that transforms some properties of an input object
问题描述
Does anyone know how one would typ a transform function where only part of the keys are known/relevant and one of the known keys are optional? E.g.
const transform = <T extends BaseAkpiDto>(akpiDTO: T) => {
const { startDate, periodData, ...akpiBase } = akpiDTO;
const withMoments = {
...akpiBase,
startDate: moment.utc(startDate),
};
if (!periodData) {
return withMoments;
}
return {
...withMoments,
lineData: akpiDtoToLineData(withMoments.startDate, periodData),
};
};
interface BaseAkpiDto {
startDate: string;
endDate: string;
periodData?: PeriodDto[];
}
const test: WithPeriodData = akpiDTOtoAkpiData({
id: 1,
name: 'my name',
startDate: '2019',
periodData: [] as PeriodDto[],
});
interface WithPeriodData {
id: number;
name: string;
startDate: Moment;
lineData: Period[];
}
I'm unable to get the return type to include a lineData property if (and only if) there is a lineData property on the input :(
Typescript complains to my test
variable with the following message:
Property 'lineData' is missing in type 'Pick<{ id: number; name: string; startDate: string; periodData: PeriodDto[]; }, "id" | "name"> & { startDate: Moment; endDate: Moment; }' but required in type 'WithPeriodData'.
解决方案
Function transform
has conditional behavior. Looking on the control flow it can return or object which contains lineData
or not. Therefor you cannot assign the return which is a union IHaveLineData
| IDoNotHaveLineData
to IHaveLineData
as the return is just wider type. Imagine you want to assign smth which is string | number
to number
, because of the same reason you can't.
To be sure you get the wanted structure you need to append additional control flow to ensure the type. So just:
// at this level test is infered as with or without lineData
const test= akpiDTOtoAkpiData({
id: 1,
name: 'my name',
startDate: '2019',
periodData: [] as PeriodDto[],
});
if ('lineData' in test) {
// here test is precisely the type with lineData
}
推荐阅读
- mysql - 如何提高这个 MySQL 7 天滚动平均查询的性能?
- r - 如何使用 R 实现自动化
- r - 如何检查给定的单词是否可以组成R中的单词?
- python-3.x - 在 python 3 中使用 strptime 以 dmY 格式解析日期和 mdY
- java - 如何使用 log4j 自定义附加程序在 HDFS 上创建日志?
- php - API 平台 - 通过 IRI 迭代资源
- javascript - 在 for 循环中使用异步等待时出现错误的请求错误
- spring - 静态 application.properties 值有效,但动态值无效
- amazon-web-services - 如何在不构建依赖项的情况下引用堆栈输出值?
- android - 升级 Google Play 服务库在错误的元数据标签上崩溃