强制对传递给TypeScript函数的变量进行属性过度检查

Mic*_*oft 6 typescript

有没有一种方法可以强制进行超属性检查,而不仅仅是对内联对象文字进行检查,而是从变量派生?

例如,假设我有一个接口和一个函数

interface Animal {
    speciesName: string
    legCount: number,
}

function serializeBasicAnimalData(a: Animal) {
    // something
}
Run Code Online (Sandbox Code Playgroud)


如果我打电话 

serializeBasicAnimalData({
    legCount: 65,
    speciesName: "weird 65-legged animal",
    specialPowers: "Devours plastic"
})
Run Code Online (Sandbox Code Playgroud)

我会得到一个错误-对于我的情况,这就是我想要的。我只希望函数接受通用的动物描述,而无需额外的细节。


另一方面,如果我首先为其创建变量,则不会收到错误消息:

var weirdAnimal = {
    legCount: 65,
    speciesName: "weird 65-legged animal",
    specialPowers: "Devours plastic"
};
serializeBasicAnimalData(weirdAnimal);
Run Code Online (Sandbox Code Playgroud)


所以我的问题是:是否有一种方法可以强制TypeScript对函数参数应用“多余的属性检查”,而不管它是内联对象还是先前已分配给变量的对象?

 

Sha*_*son 15

希望这会有所帮助,这将导致它失败。造成这种情况的根本原因是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
Run Code Online (Sandbox Code Playgroud)

  • 这感觉就像深奥的魔法,我不认为我自己可以给出这样的答案,但它仍然很棒。谢谢一堆! (4认同)
  • 名义类型也有它的位置。这并不像一个比另一个更好那么简单。 (2认同)
  • 谢谢。你知道 2020 年是否有更简单/更易读的方法来做到这一点吗? (2认同)
  • 任何基于 TypeScript 的解决方案通常只是编译时,请小心 TypeScript 中的类型,因为它们没有任何运行时语义,如 C# 或 Java (2认同)