Я утверждал, что результаты вызова API имеют следующую форму в TypeScript:
interface Res {
films: string;
people: string;
}
const res: Res = await fetch("https://swapi.dev/api/")
.then((res) => {
return res.json();
})
.then(({ films, people }) => {
return {
films,
people,
};
});
Позже я добавил проверку типов во время выполнения с помощью Zod.
const resSchema = z.object({
films: z.string(),
people: z.string(),
});
resSchema.parse(res);
Это работает, но это означает, что мне нужно поддерживать 2 разных определения типа. Есть ли способ проверить в TypeScript, что тип resSchema
равен Res
?
Я знаю, что Зод может сделать вывод:
type ResType = z.infer<typeof resSchema>
const res: ResType = await fetch("https://swapi.dev/api/")
.then((res) => {
return res.json();
})
.then(({ films, people }) => {
return {
films,
people,
};
});
Однако я не хочу использовать это, так как я не могу сразу увидеть поля на ResType
по сравнению с Res
, что очень ясно.
Вы можете сделать это, утверждая тип схемы, а не выводя типы из схемы. В вашем примере, если у вас уже есть интерфейс Res
, вы можете определить свой schema
как:
import { z } from "zod";
interface Res {
films: string;
people: string;
}
const schema: z.ZodType<Res> = z.object({
films: z.string(),
people: z.string(),
});
Если вы обновите Res
, вы получите ошибку типа в строке, где вы определили schema
, что значение z.object
больше не может быть присвоено указанному вами ZodType
.
У этого также есть приятное свойство: возвращаемое значение из schema.parse
будет отображаться как Res
в вашем редакторе. Если вы дадите интерфейсу значимое имя и комментарии в стиле javadoc, они будут присвоены возвращаемым значениям из parse
на языковом сервере вашего редактора.