如何在 TypeScript 中合并两个函数定义?
How can I merge two function definitions in TypeScript?
我有以下create
函数,它有两个定义:
// Definition 1
export async function create<Entity>(
entity: ObjectType<Entity>,
data: DeepPartial<Entity>
): Promise<Entity>;
// Definition 2
export async function create<Entity>(
entity: ObjectType<Entity>,
data: DeepPartial<Entity>,
pickValues: keyof Entity
): Promise<Partial<Entity>>;
// Implementation
export async function create<Entity>(
entity: ObjectType<Entity>,
data: DeepPartial<Entity>,
pickValues?: keyof Entity
): Promise<Entity | Partial<Entity>> {
const { manager } = await connectDatabase();
const instance = manager.create(entity, data);
const createdEntity = await manager.save(instance);
return typeof pickValues === 'undefined'
? createdEntity
: pick(createdEntity, pickValues);
}
有没有办法在函数实现的类型中合并这两个定义?也许有条件 return 类型...像这样的东西:
A extends B ? c : d;
确实可以为此使用条件 return 类型。我们需要做的是为 pickValues
参数引入一个通用类型,这样我们就可以将它用于 return 类型:
export async function create<Entity, PickValues extends keyof Entity | undefined = undefined>(
entity: ObjectType<Entity>,
data: DeepPartial<Entity>,
pickValues?: PickValues
): Promise<PickValues extends undefined ? Entity : Partial<Entity>> {
const { manager } = await connectDatabase();
const instance = manager.create(entity, data);
const createdEntity = await manager.save(instance);
return (typeof pickValues === 'undefined'
? createdEntity
: pick(createdEntity, pickValues as keyof Entity)) as any;
}
不幸的是,由于 TypeScript 的设计限制,它并不真正理解 return 类型应该根据 pickValues
(github issue) 的值而有所不同。因此,我们必须将 return 值转换为 any
才能使其正常工作。
由于必要的转换和增加的复杂性,我建议坚持使用重载以获得更好的可读性。
注意:TypeScript 实际上有一个实用程序类型 Pick
可以让您更加具体。您可以在 return 类型中使用 Pick<Entity, Exclude<Values, undefined>>
而不是 Partial<Entity>
。
我有以下create
函数,它有两个定义:
// Definition 1
export async function create<Entity>(
entity: ObjectType<Entity>,
data: DeepPartial<Entity>
): Promise<Entity>;
// Definition 2
export async function create<Entity>(
entity: ObjectType<Entity>,
data: DeepPartial<Entity>,
pickValues: keyof Entity
): Promise<Partial<Entity>>;
// Implementation
export async function create<Entity>(
entity: ObjectType<Entity>,
data: DeepPartial<Entity>,
pickValues?: keyof Entity
): Promise<Entity | Partial<Entity>> {
const { manager } = await connectDatabase();
const instance = manager.create(entity, data);
const createdEntity = await manager.save(instance);
return typeof pickValues === 'undefined'
? createdEntity
: pick(createdEntity, pickValues);
}
有没有办法在函数实现的类型中合并这两个定义?也许有条件 return 类型...像这样的东西:
A extends B ? c : d;
确实可以为此使用条件 return 类型。我们需要做的是为 pickValues
参数引入一个通用类型,这样我们就可以将它用于 return 类型:
export async function create<Entity, PickValues extends keyof Entity | undefined = undefined>(
entity: ObjectType<Entity>,
data: DeepPartial<Entity>,
pickValues?: PickValues
): Promise<PickValues extends undefined ? Entity : Partial<Entity>> {
const { manager } = await connectDatabase();
const instance = manager.create(entity, data);
const createdEntity = await manager.save(instance);
return (typeof pickValues === 'undefined'
? createdEntity
: pick(createdEntity, pickValues as keyof Entity)) as any;
}
不幸的是,由于 TypeScript 的设计限制,它并不真正理解 return 类型应该根据 pickValues
(github issue) 的值而有所不同。因此,我们必须将 return 值转换为 any
才能使其正常工作。
由于必要的转换和增加的复杂性,我建议坚持使用重载以获得更好的可读性。
注意:TypeScript 实际上有一个实用程序类型 Pick
可以让您更加具体。您可以在 return 类型中使用 Pick<Entity, Exclude<Values, undefined>>
而不是 Partial<Entity>
。