type FromType = {
// [...]
value: string;
}
type ToType = Omit<FromType, 'value'> & {
value: number;
}
然后
/**
* @param {FromType[]} records
* @returns {ToType[]} records
*/
function transform(records){
return records.map((record) => {
record.value = parseFloat(record.value);
return record;
});
}
抱怨因为
record.value
应该是一个字符串。解决方法是使用 Object.assign
/**
* @param {FromType[]} records
* @returns {ToType[]} records
*/
function transform(records){
return records.map((record) => {
return Object.assign(record, {
value: parseFloat(record.value),
});
});
}
如何处理作业的类型转换?
假设:
string | number
.{ ...item, value: 0 }
;抱歉,我不知道如何使用 JSDoc 对此进行注释,但是使用 TypeScript 自己的类型注释来执行该突变,您会短暂地对 TypeScript 撒谎以欺骗它允许它:
type FromType = {
// [...]
value: string;
};
type ToType = Omit<FromType, "value"> & {
value: number;
};
type X = ToType["value"];
/**
* @param records The record to transform.
* @returns Transformed records.
*/
function transform(records: FromType[]): ToType[] {
return records.map((record) => {
const result = record as any as ToType; // A brief lie...
result.value = parseFloat(record.value); // ...which is now true
return result;
});
}
如果你能避免突变,我会强烈鼓励它(那就是
return records.map((value, ...rest) => ({...rest, value: parseFloat(value)}));
),但如果你不能避免它,你就无法避免它。 :-)
因为你正在改变对象,除非你有一个非常不寻常的用例,否则没有理由创建一个新数组,不这样做也可能有助于解决你的性能问题:
/**
* @param records The record to transform.
* @returns The **same** array, objects are mutated in place.
*/
function transform(records: FromType[]): ToType[] {
for (let n = records.length - 1 ; n >= 0; --n) {
const record = records[n];
const result = record as any as ToType; // A brief lie...
result.value = parseFloat(record.value); // ...which is now true
}
return records as any as ToType[];
}
即使您确实需要创建一个新数组,鉴于此函数正在适当地发生变化,让调用者做的事情可能是有意义的(也许通过
slice
,这非常快)。
Object.assign
尽善尽美(打字除外)type FromType = {
value: string;
};
function transform1(records: FromType[]) {
return records.map((record) => {
return override(record, 'value', parseFloat(record.value))
});
}
type R1 = ReturnType<typeof transform1>
// ^?
// type R1 = { value: number; }[]
function transform2(records: FromType[]) {
return records.map((record) => {
return assign(record, { value: parseFloat(record.value) })
});
}
type R2 = ReturnType<typeof transform2>
// ^?
// type R2 = { value: number; }[]
type Pure<T> = { [K in keyof T]: T[K] }
function override<O, K extends PropertyKey, V>(o: O, k: K, v: V): { [P in (keyof O) | K]: P extends K ? V : O[P & keyof O] } {
(o as Record<K, V>)[k] = v;
return o as any;
}
function assign<O extends object, V extends object>(o: O, v: V): { [P in keyof O | keyof V]: P extends keyof V ? V[P] : O[P & keyof O] } {
return Object.assign(o, v) as any;
}