我有下面的代码,代表两个接口和两个对象。然而,问题是如何创建一个通用的 predicate 函数,检查传递的对象是否符合上述接口。我尝试了 predicate 的其他实现,但它们显示了误报,因为在核心中,对象应该符合一个接口,而不是其他对象。
export const willObjectAdhereToInterface = <T>(item: any): item is T => {
// Check for null and undefined only
if (item === null || item === undefined) {
return false;
}
// Check it is an object
if (typeof item !== 'object') {
return false;
}
// Get the expected keys of type T
const expectedKeys: Array<keyof T> = Object.keys({} as T) as Array<keyof T>;
// Check if all keys of T are present in the item
return expectedKeys.every((key) => key in item);
};
interface A {
a1: string;
a2: string;
}
interface B {
b1: string;
b2: string;
diffrence1: number;
diffrence2: number;
}
const a: A = {
a1: 'a1',
a2: 'a2',
};
const b: B = {
b1: 'b1',
b2: 'b2',
diffrence1: 0,
diffrence2: 1,
};
if(willObjectAdhereToInterface<A>(a)){
// a is deffinatly of A interface
}
if(willObjectAdhereToInterface<B>(b)){
// a is deffinatly of B interface
}
if(willObjectAdhereToInterface<A>(b)){
console.log(b.a1) // must show an error.
}
字符串
至于我目前所做的是这2个通用函数,一个将检查对象,但它必须有所需的键来检查(不太好),另一个是检查使用第一个函数的set State action。
// T will represent the interface of the state
export const isGenericObject = <T>(object: any, requiredFields: string[] /* Pass the keys */): object is Partial<T> | T => {
// Check for null and undefined only
if (object === null || object === undefined) {
return false;
}
// Check if object
if (typeof object !== 'object') {
return false;
}
// Retrieve keys from the item
const keys = Object.keys(object);
// Check if all required fields are present
const hasAllRequiredFields = requiredFields.every((field) => keys.includes(field));
return hasAllRequiredFields;
};
const isGenericSetState = <T>(object: any, setState: any): setState is Dispatch<SetStateAction<T>> => {
// Check for null or undefined
if (setState === null || setState === undefined) {
return false;
}
// Check if setState has the expected type
if (typeof setState !== 'function') {
return false;
}
if (object !== undefined && isGenericObject(object, Object.keys(object))) {
return true;
}
return false;
};
型
1条答案
按热度按时间v7pvogib1#
您混合了运行时(JavaScript)和编译时(TS类型)代码。运行时中不存在接口,因此您无法编写检查对象是否符合接口的代码。
如果你想检查运行时对象,那么最好的选择是你已经写过的
isGenericObject
,通过输入required fields属性进行了一点改进:字符串
这一额外的论点是无法回避的。
您唯一可以做的其他事情是将接口转换为类,然后传递类本身,而不是必需的字段数组
型
但是这需要你为每个类型创建一个构造函数,它将初始化所有必需的键,这比创建数组更糟糕。
有一种不同的方法你可以采取,但只有当你想在编译时的错误,并不会检查agains对象,你不知道他们是什么。这是使用
extends
来检查是否有效的东西:型