作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在将一堆 typescript 类型扩展到实用程序库中,作为个人“我真的了解 typescript 吗?”项目。
我只是在弄清楚如何对这该死的东西进行单元测试时遇到了很多麻烦。
问题是我想测试当我将错误的类型传递给调用类型的函数时,TSC 是否会捕获它。它的作用。辉煌。但是有一个很小的缺陷,因为我使用的单元测试库 (Jest) 会抛出一个错误(所需的行为),然后拒绝运行测试套件的其余部分,因为它抛出了一个错误。我什至不能使用“会抛出错误”,因为它不是 Javascript 错误而是 Typescript 错误。
这是我到目前为止的代码。我正在使用 Jest,但我的解决方案不需要特定于 Jest,我有一种有趣的感觉,我可能需要某种专门的测试库。
// src/Either/Either.ts
export type Either<Base, Either, Or> = (Base & Either) | (Base & Or);
// src/either/Either.spec.ts
import { Either } from "./Either";
interface Pet {
name: string;
}
interface Dog {
says: "awoo" | "ruff" | "yip" | "bork" | "bark" | "grr";
willFetch: true;
}
interface Cat {
says: "meow" | "hiss";
willFetch: false;
}
describe("Either<Base, Either, Or>", () => {
it("allows one extension OR the other, but not both, and not neither", () => {
type CommonPet = Either<Pet, Dog, Cat>;
const whatAmI = (pet: CommonPet): "dog" | "cat" => {
if (pet.willFetch === true) {
return "dog";
}
return "cat";
};
expect(whatAmI({ name: "Rex", willFetch: true, says: "awoo" })).toBe("dog");
expect(whatAmI({ name: "Psycho", says: "hiss", willFetch: false })).toBe(
"cat"
);
// these lines will throw a typescript error (desired)
/*
const freak = whatAmI({ name: "Freak", says: "meow", willFetch: true });
const uncommonPet = whatAmI({ name: "Nagini", says: 'hiss', willFetch: false, isSnake: true });
*/
// but how to I tell Jest that I WANT it to throw a typescript error?
interface AristoCat {
knowsWhereItsAt: boolean;
}
interface JellicleCat {
nightmareFuel: number;
}
type MusicalCat = Either<Pet & Cat, AristoCat, JellicleCat>;
const isGood = (cat: MusicalCat): boolean | never => {
if ("knowsWhereItsAt" in cat) {
return true;
}
if (cat.nightmareFuel > 0) {
throw new Error("NOOOOOO!");
}
return false;
};
expect(
isGood({
name: "Duchess",
says: "meow",
willFetch: false,
knowsWhereItsAt: true
})
).toBe(true);
expect(
isGood({
name: "MacCavity (stage)",
willFetch: false,
says: "meow",
nightmareFuel: 0
})
).toBe(false);
const filmIt = () =>
isGood({
name: "MacCavity",
willFetch: false,
says: "meow",
nightmareFuel: 9001
});
expect(filmIt).toThrowErrorMatchingInlineSnapshot(`"NOOOOOO!"`);
// again, we expect this to throw in TYPESCRIPT because it has BOTH.
/*
const dreamIHadOnAcid = isGood({
name: 'Cheshire',
says: 'meow',
willFetch: false,
knowsWhereItsAt: true,
nightmareFuel: 5/7
})
*/
// again, we expect this to throw in TYPESCRIPT because it has NEITHER.
/*
const dreamIHadOnAcid = isGood({
name: 'Tardar Sauce',
says: 'meow',
willFetch: false,
})
*/
});
});
export type Either<Base, Either, Or> = (Base & Either) | (Base & Or);
type Pet = {
name: string;
says?: string;
}
type DogExtension = {
playHours: number;
}
type CatExtension = {
sleepHours: number;
}
type CommonPet = Either<Pet, DogExtension, CatExtension>;
const dog: CommonPet = { name: "rex", says: "awoo", playHours: 5 };
const cat: CommonPet = { name: "manx", says: "meow", sleepHours: 14 };
const testPet = (testName: string, pet: CommonPet): CommonPet => {
return pet
};
testPet("dog should pass", dog);
testPet("cat should pass", cat);
testPet("catdog should not pass", { ...dog, ...cat }); /* should throw a type error, but doesn't */
最佳答案
我之前遇到过这个问题并设法让它与 dtslint 一起工作.我发现这些测试对于编写包含大量泛型类型逻辑的库非常有值(value),因为我经常遇到修复一件事会导致其他地方错误推断类型的情况。
这是the repo我设法让它工作的地方。具体来说,this file包含其中一项测试。可以使用 yarn type-check
运行类型测试或 npm run type-check
.
当某些事情失败时,您会收到如下错误:
Error: /good-form/types/Field.types.ts:19:3
ERROR: 19:3 expect TypeScript@local expected type to be:
number
got:
string
关于typescript - 如何在 Typescript 中测试泛型类型?不是泛型类型的实现,而是作为类型保护?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59494889/
我是一名优秀的程序员,十分优秀!