想象我有两个界面:
interface A {
foo: boolean,
bar: string,
baz: string
}
interface B {
foo: number,
bar: string,
baz: string
}
现在我有一个实现接口A
的对象,但是我需要将其传递给需要接口B
的函数。我当然可以做:
const another_object: B = {
foo: original_object.foo? 1 : 0,
bar: original_object.bar,
baz: original_object.baz
}
但是,如果A和B包含许多字段,则此表示法将很不方便。 在TypeScript中还有更好的方法吗?
答案 0 :(得分:1)
您可以使用传播运算符使此操作更简单:
contract
TypeScript可以使此操作更容易。准备好后,我将更新此答案。
更新: 上面的答案就足够了。 我想到的是一个覆盖范围更广的用例,该用例具有不兼容的类型,同时保留其余部分。
如果您要查找的是,可以在type-plus
中检出const another_object: B = {
...original_object,
foo: orignial_object.foo? 0: 1
}
函数。
类型有点复杂。 这是主要的逻辑:
typeOverrideIncompatible()
export type ANotB<A extends object, B extends object> =
IsSame<A, B> extends true ? never :
IsDisjoint<A, B> extends true ? A :
{
[k in Exclude<keyof A, keyof B> | KeysWithDiffType<A, B>]: A[k]
}
来自集合论,表示ANotB
中的属性,而不是A
中的属性。
答案 1 :(得分:0)
我使用的数据库不接受布尔值,仅接受数字,但是在控制器逻辑中,我想对布尔值进行操作。
– dffsfs
如果这是唯一必要的转换,是的,可以使用反射来实现。
interface A {
foo: boolean
bar: string
baz: string
}
interface B {
foo: number
bar: string
baz: string
}
type U<T> = {
[K in keyof T]: T[K] extends boolean ? number : T[K]
}
function toDbObject<T> (value: T): U<T> {
return Object.entries(value).reduce<Partial<U<T>>>(
(dbObject: Partial<U<T>>, [key, value]) => Object.assign(
dbObject, { [key]: typeof value === 'boolean' ? +value : value }
),
{}
) as U<T>
}
const a: A = {
foo: true,
bar: 'bar',
baz: 'baz'
}
const b: B = toDbObject(a)
显然,U
在这里不是一个好的名称,因此您应该使用一个更具描述性的名称,以适用于您的用例。
如果您的lib
包含esnext
,则可以使用Array.prototype.map()
和Object.fromEntries()
代替Array.prototype.reduce()
。
function toDbObject<T> (value: T): U<T> {
return Object.fromEntries(
Object.entries(value).map(
([key, value]) => [key, typeof value === 'boolean' ? +value : value]
)
) as U<T>
}