是否有一种方法可以强制进行多余属性检查,而不仅限于内联对象文字,而且还可以从变量派生?
例如,假设我有一个接口和一个函数
interface Animal {
speciesName: string
legCount: number,
}
function serializeBasicAnimalData(a: Animal) {
// something
}
如果我打电话
serializeBasicAnimalData({
legCount: 65,
speciesName: "weird 65-legged animal",
specialPowers: "Devours plastic"
})
我会得到一个错误-对于我的情况,这就是我想要的。我只希望该函数接受通用的动物描述,而无需额外的细节。
另一方面,如果我首先为它创建一个变量,我不会得到错误:
var weirdAnimal = {
legCount: 65,
speciesName: "weird 65-legged animal",
specialPowers: "Devours plastic"
};
serializeBasicAnimalData(weirdAnimal);
所以我的问题是:是否有一种方法可以强制TypeScript对函数参数应用“多余的属性检查”,而不管它是内联对象还是先前已分配给变量的对象?
答案 0 :(得分:6)
希望这会有所帮助,这将导致它失败。造成这种情况的根本原因是Typescripts依赖于结构化类型,这比名义类型化要好得多,但是仍然存在问题。
type StrictPropertyCheck<T, TExpected, TError> = Exclude<keyof T, keyof TExpected> extends never ? {} : TError;
interface Animal {
speciesName: string
legCount: number,
}
function serializeBasicAnimalData<T extends Animal>(a: T & StrictPropertyCheck<T, Animal, "Only allowed properties of Animal">) {
// something
}
var weirdAnimal = {
legCount: 65,
speciesName: "weird 65-legged animal",
specialPowers: "Devours plastic"
};
serializeBasicAnimalData(weirdAnimal); // now correctly fails
答案 1 :(得分:0)
我需要它来在Redux中强制执行对象形状。
我已将article的出色答案与此线程here的香农的答案结合在一起。我认为这为实现此目标提供了更简洁的方法:
export type StrictPropertyCheck<T, TExpected, TError> = T extends TExpected
? Exclude<keyof T, keyof TExpected> extends never
? T
: TError
: TExpected
在这里^^我将T extends TExpected
放在了StrictPropertyCheck
中,这实际上是所有区别,但是我认为链接上面的文章将有助于其他人进入该线程。
export type Credentials = {
email: string
password: string
}
export type StrictCreds<T> = T &
StrictPropertyCheck<
T,
Credentials,
'ERROR: THERE ARE EXCESS PROPERTIES IN CREDENTIALS OBJECT'
>
export type AuthActionType =
| {
type: AuthAction.LOGIN
payload: StrictCreds<Credentials>
}
| { type: AuthAction.LOGOUT
export const login = <T>(credentials: StrictCreds<T>): AuthActionType => {
return {
type: AuthAction.LOGIN,
payload: credentials as Credentials,
}
}