将通用类型投射到诸如Product,Post,Todo,Customer等实体的任何作品(E类型将是打字稿类型,类或接口):
function test<E>(o:E):string {
return (o as any)['property']
}
只想看看是否强制转换为任何对象?
要求提供完整的上下文。这是正在执行的全部功能:
/**
*
* @param entities The entities to search
* @param exclude Keys to exclude from each entity
*
* @return E[] Array of entities with properties containing the search term.
*/
export function search<E extends WithProperty>(query:string='', entities:E[], exclude:string[]=[]) {
const { isArray } = Array
query = query.toLowerCase();
let keys:string[] = []
if (entities.length > 0) {
keys = excludeKeys(entities[0], exclude)
}
return entities.filter(function (e:E) {
return keys.some((key)=>{
const value = (e as any)[key];
if (isArray(value)) {
return value.some(v => {
return new String(v).toLowerCase().includes(query);
});
}
else if (!isArray(value)) {
return new String(value).toLowerCase().includes(query);
}
})
});
}
/**
* The method can be used to exclude keys from an instance
* of type `E`.
*
* We can use this to exclude values when searching an object.
*
* @param entity An instance of type E
* @param eclude The keys to exclude
*
*/
export function excludeKeys<E>(entity: E, exclude: string[]) {
const keys: string[] = Object.keys(entity);
return keys.filter((key) => {
return exclude.indexOf(key) < 0;
});
}
答案 0 :(得分:2)
如果您知道类型约束具有名为属性的属性,则可以定义一个接口,该接口定义该属性,然后使用告诉E对其进行扩展的约束。然后您将可以访问该属性而无需强制转换。
interface WithProperty{
property:string;
}
function test<E extends WithProperty>(o:E):string {
return o.property; // or o["property"] is valid access.
}
编辑:
自从您更新了示例。还有另一种方法可以使用关键字keyof
。同样,使用此不需要知识的属性。我已经修改了您的示例,如下所示:
export function search<E>(query:string='', entities:E[], exclude:string[]=[]) {
const { isArray } = Array
type EKey = keyof E;
query = query.toLowerCase();
let keys : EKey[] = []
if (entities.length > 0) {
keys = excludeKeys<E>(entities[0], exclude)
}
return entities.filter(function (e:E) {
return keys.some((key =>{
const value = e[key];
if (isArray(value)) {
return value.some(v => {
return v.toLowerCase().includes(search);
});
}
else if (!isArray(value)) {
return new String(value).toLowerCase().includes(query);
}
})
});
}
由于这种discussion的紧迫性,对于代码的excludeKeys部分来说,这是不可避免的。
export function excludeKeys<E>(entity: E, exclude: string[]) {
const keys: string[] = Object.keys(entity);
return <(keyof E)[]>keys.filter((key) => {
return exclude.indexOf(key) < 0;
});
}