【问题标题】:How to infer the right types of component's @Input如何推断组件的@Input 的正确类型
【发布时间】:2021-03-03 15:31:23
【问题描述】:

我正在寻找一种方法来推断组件的@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: () => {});

【问题讨论】:

  • setComponentInputs&lt;T&gt;(props: Partial&lt;T&gt;) ... 会为您工作吗?请参阅typescriptlang.org/docs/handbook/utility-types.html 了解更多信息
  • 事实上,确实如此!我可以通过使用props: { [P in keyof T]?: T[P] } 来解决它,但你的方法更干净。感谢凉爽的微风!
  • 还有一个问题...即使使用您或我的解决方案,我仍然可以访问函数(例如 NgOnInit),理想情况下我应该只能设置属性。
  • 试试这个:props: { [P in keyof T]?: T[P] extends Function ? never : T[P] }
  • 不,那不一样。排除从联合中排除某些类型,并且不适用于某些对象值

标签: angular typescript strong-typing


【解决方案1】:

在输入中,您可以使用“强制”,例如 this entry from 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}){}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    相关资源
    最近更新 更多