Made a basic example to show what I'm trying to accomplish:

基本上给出了这两种类型:

type BaseType = FormGroup<{
  user: FormControl<string>;
}>;

type SomeOtherType = FormGroup<{
  user: FormControl<string>;
  amount: FormControl<number>;
}>;

我希望能够将SomeOtherType传递给类型为BaseType的组件的输入,因为它们完成了合同.

正常情况下,try 执行此操作时,我似乎得到了一个向后错误:

Type 'SomeOtherType' is not assignable to type 'BaseType'.
Property 'amount' is missing in type '{ user: FormControl<string>; }' but required in type '{ user: FormControl<string>; amount: FormControl<number>; }'.

我可以通过使用输入转换来消除所有限制

@Input({ required: true, transform: (value: FormGroup): BaseType => value })
form!: BaseType;

但我不喜欢将任何表单组限制为与基类型匹配的对象时,如何才能传递它.

(帮助阻止任何关于为什么不用其他方式做这件事的问题.这是一个已经完成的产品的一部分,我正在try 将它从untyped个表单everywhere迁移到新键入的表单.对于非类型化表单,一切都运行得很好,依赖于表单控件子集的组件也没有问题,只是希望能够保留该功能,但同时使用新的键入功能.)

推荐答案

FormGroup的定义有一些地方不允许与表单控件子类型的协变.换句话说,{user: FormControl, amount: FormControl}{user: FormControl}的子类型,FormGroup<{user: FormControl, amount: FormControl}> 104FormGroup<{user: FormControl>的子类型.

FormGroup扩展AbstractControl,您的问题似乎是由于控件的值是如何派生的.(这一结论是通过反复试验得出的,因为正在进行的体操类型令人费解.)

由于问题归结为FormGroup如何扩展AbstractControl,我们可以使用有区别的联合来使BaseType更灵活一些,同时仍然保持相当好的类型定义.

type BaseTypeValue = {
  user: string;
};

type BaseTypeFormControls = { 
  [K in keyof BaseTypeValue]: FormControl<BaseTypeValue[K]> 
}

type BaseType = 
  FormGroup<BaseTypeFormControls>
  | AbstractControl<Partial<BaseTypeValue>, BaseTypeValue>;

StackFlash

Angular相关问答推荐

使用注入的主机组件进行指令测试

声明Angular material 中按钮的自定义 colored颜色

使用Angular 13的NgxPrinterService打印时,第二页上的空白区域

HTTP POST响应失败Angular 16

在Cypress中,对xlsx文件的读取并不总是正确的

nx serve正在忽略@angular/localize/init的导入"

在Angular 17的本地服务应用程序时禁用SSR

基于RxJS的Angular 服务数据缓存

合并Cypress和Karma的代码覆盖率报告JSON文件不会产生正确的结果

如何检测 Angular Universal 预渲染版本?

在生产模式下使用带Angular 的 livekit

Angular 没有可用于依赖类型的模块工厂:ContextElementDependency

如何在angular material中使用输入类型文件

Angular 2 - 什么是Root Scope?

如何在 Angular 6 中使用 mouseover 和 mouseout

ng add 与 npm install 在 Angular 6 中的区别

如何在 Angular 5 react式表单输入中使用管道

ng build 时超出调用重试次数异常

如何在 Angular 2 中跟踪路由?

Angular2:无法读取未定义的属性名称