【发布时间】: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<T>(props: Partial<T>) ...会为您工作吗?请参阅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