如何设置MikroORM FindOneOrFailOptions参数的属性类型,以便提前收集 &g



我正在做一个打字稿项目,在某些时候,我需要提前从microorm收集FindOneOrFailOptions参数。

代码要复杂得多,但我已经设法用更少的行复制了这个问题。

下面的代码没有问题:

class ProviderRepository {
public async findOneByUrl(url: string): Promise<Provider> {
const repository = /* is of type EntityRepository<Provider> */
return await repository.findOneOrFail({ url }, { populate: ['profile'] });
}
}

下面这个失败了,因为升高了TS2345: Argument of type '{ populate: string[]; }' is not assignable to parameter of type 'FindOneOrFailOptions<Provider, string>'.:

class ProviderRepository {
public async findOneByUrl(url: string): Promise<Provider> {
const repository = /* is of type EntityRepository<Provider> */
const options = { populate: ['profile'] };
return await repository.findOneOrFail({ url }, options);
-------
}
}

显然,解决方案应该是将options声明为FindOneOrFailOptions<Provider, string>。但是,如果我这样做,那么它会引发TS2322: Type 'string' is not assignable to type 'never'.:

class ProviderRepository {
public async findOneByUrl(url: string): Promise<Provider> {
const repository = /* is of type EntityRepository<Provider> */
const options: FindOneOrFailOptions<Provider, string> = { populate: ['profile'] };
     ---------
return await repository.findOneOrFail({ url }, options);
}
}

在这一点上,我有点迷失了如何继续。我假设这里的never来自函数声明:

class EntityRepository<T extends AnyEntity<T>> {
findOneOrFail<P extends string = never>(where: FilterQuery<T>, options?: FindOneOrFailOptions<T, P>): Promise<Loaded<T, P>>;
}

然而,即使我像repository.findOneOrFail<string>(...)一样使用这个函数,它仍然产生相同的错误。我认为必须有某种自动转换,如果我内联参数,即使没有<string>,它也很高兴没有问题。这告诉我,我还没有确定它所期望的确切类型,但我对这种类型可能是什么有点无能为力。

如何提前声明options参数而不会出现任何问题?很多谢谢!

不能只输入string,如果我们允许这样做,我们就失去了类型安全性,因为任何字符串都可以使用。它需要是具有实际值的字符串文字类型。对于您的特定用例,const断言应该完成这项工作:

await repository.findOneOrFail({ url }, { populate: ['profile'] as const });

我怎么能有选项参数声明提前没有任何问题?很多谢谢!

你不能真的预先定义它并期望任何类型安全,因为它与实际值没有联系——如果你想要的话,你需要自己强制转换。或者将类型参数设置为any,这不是很好,但实际上它是您想要的最精确的描述,因为它禁用了填充提示的严格类型。这是允许在创建这样的对象后设置更多填充提示的唯一方法。

const options: FindOneOrFailOptions<Provider, any> = { populate: ['profile'] };
options.populate.push('otherProp');

如果你只想创建一个对象,并且你知道它只包含一个项目,你可以显式传递类型值。

const options: FindOneOrFailOptions<Provider, 'profile'> = { populate: ['profile'] };

如果你不提供第二个类型参数,默认是never-所以没有它你永远不能传递任何东西给populate提示。

最新更新