我想创建一个通用的TypeScript类,用于渲染(作为HTML列表)实现特定TypeScript接口的对象数组。
e.g。
class GenericListRenderer<T> {
items: T[];
constructor(listItems: T[], className?: string){
this.items = listItems;
...
}
private getPropertyNames(): string[]{
// What is the best way to access all property names defined in
// TypeScript interface 'T' that was used in this generic?
...
}
render(){
var propNames: string[] = this.getPropertyNames();
// render list with each item containing set of all
// key(prop name)/value pairs defined by interface 'T'
...
}
}
问:什么是获得编译时间的最佳方式?指定的()TypeScript接口中定义的所有属性名称的列表?
与C ++模板一样,我相信当TypeScript类型信息(如提供给用于实例化特定对象的泛型的接口)随时可用时,TypeScript可以在#34;编译时&#34;期间解析这些泛型。
由于可能提供了所有必需的类型信息,我只是好奇是否有可用的TypeScript扩展/工具来访问此信息而不会过度运行时过滤&#39; vanilla&#39; Javascript对象 - 由于模糊的继承问题可能会出现问题(例如,如果运行时,泛型,Javascript(obj.hasOwnProperty(prop))用于过滤属性,则可能会过滤掉所需的TypeScript继承的接口属性。)
这个有用的属性内省潜力可以通过TypeScript的超级类型元数据在编译时间内明确地解决。 vs当尝试在翻译的Javascript中解析此信息时,将丢弃所有此类型信息。
我讨厌重新发明轮子&#39;如果存在标准(TypeScript)方法,则可能存在不完善的Javascript攻击。
此致: 初学者TypeScript Guy, 约翰
答案 0 :(得分:14)
这可以通过使用https://github.com/Microsoft/TypeScript/pull/13940引入的自定义变换器来实现,该变换器可以在typescript @ next中找到。
我的npm包ts-transformer-keys
就是一个很好的例子。
import { keys } from 'ts-transformer-keys';
interface Props {
id: string;
name: string;
age: number;
}
const keysOfProps = keys<Props>();
console.log(keysOfProps); // ['id', 'name', 'age']
答案 1 :(得分:6)
这不可能在运行时检索这些信息,除非您在编译期间存储它们,否则它们永远不会是默认的。因此,解决方案是使用ReflectDecorators进行反思。
Here是一篇很好的文章,涵盖了在运行时检索编译时元数据的问题。简而言之:你想要保留描述的接口添加一个装饰器,这个将被转换为一个json对象,一个将被存储到代码本身。在运行时,您将能够检索具有所有接口数据的此json对象。现在这是实验性的(2016年2月11日),但是很好。
注意:默认情况下永远不会出现这种情况的原因基本上是ts的设计选择,不要使用元数据重载js代码(与Dart不同)。
答案 2 :(得分:0)
您可以通过致电获取所需的所有信息
let test = Object.keys(instanceOfObject)
如果您登录此 console.log(test),则会得到类似的内容:
0: "user_id"
...
26: "address"
length: 27
您可以访问有关该对象的所有信息,例如test.length等。
发件人:https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
答案 3 :(得分:-1)
在运行时,所有类型信息都将被删除,因此您可以做的最好的事情是枚举其中一个对象的属性。这将返回所有属性,甚至是那些不在指定接口上的属性。
class GenericListRenderer<T> {
constructor(private items: T[], private className?: string){
}
private getPropertyNames(): string[] {
var properties: string[] = [];
if (this.items.length > 0) {
for (var propertyName in this.items[0]) {
console.log(propertyName);
properties.push(propertyName);
}
}
return properties;
}
render(){
var propNames: string[] = this.getPropertyNames();
}
}
class Example {
constructor(public name: string) {
}
}
var example = new Example('Steve');
var a = new GenericListRenderer<Example>([example]);
a.render();
还有Object.keys()
,它可以为您提供所有属性,但仅在IE9及更高版本中支持。
如果您可以为要对属性执行的操作提供更多用例,则可以使用属性或其他机制为您提供备用解决方案。