首页 > 解决方案 > 如何推断组件的@Input 的正确类型

问题描述

我正在寻找一种方法来推断组件的@Inputs 的正确类型。到目前为止,我只能@Input使用以下内容来定位属性:

// Method in a service
setComponentInputs<T> (props: { [key in keyof T]?: any }) {
   console.log(props);
}

但是正如您所看到的,该类型仍然是any
另外,当前的方法允许针对组件内的所有内容,包括方法(例如 OnInit),但我不太确定是否存在仅针对 @Inputs 的技巧。

让我为您提供更多上下文,这是一个标准的 Angular 组件:

@Component({
  selector: '',
  templateUrl: './foo.component.html',
  styleUrls: ['./foo.component.scss']
})
export class FooComponent implements OnInit {
  @Input() myProp: string;
  @Input() otherProp: CustomProp;

  constructor() {}

  ngOnInit() {
  }
}

这个想法是setComponentInputs(props)在限制 props 参数以匹配组件@Inputs属性的同时调用

// this one should compile
myService.setComponentInputs<FooComponent>({myProp: 'Hello there!'});

// this one should raise an error (because the type of myProp is string)
myService.setComponentInputs<FooComponent>({myProp: 123});

// this one should raise an error (because the referenced property don't even exist)
myService.setComponentInputs<FooComponent>({newProp: 'Hello!'});

编辑 1:我找到了一种使用映射类型来克服主要问题的方法

// Method in a service
setComponentInputs<T> (props: { [P in keyof T]?: T[P] }) {
   console.log(props);
}

但随后@andrei 指出了一种不同且更简单的方法:

// Method in a service
setComponentInputs<T> (props: Partial<T>) {
   console.log(props);
}

剩下的部分将是如何只允许属性而排除函数(例如 OnInit)

// this one should raise an error (because ngOnInit is a Function)
myService.setComponentInputs<FooComponent>({ngOnInit: () => {});

标签: angulartypescriptstrong-typing

解决方案


在输入中,您可以使用“强制”,请参阅Tomasz Kula 的此条目,例如

private _value: number;
get value(): number {
  return this._value;
}
@Input()
set value(value: number) {
  this._value = coerceNumberProperty(value, 0);
}

定义函数时可以指明类型

setComponentInput(value:{'myProp':string}){}

推荐阅读