import type { NextApiRequest, NextApiResponse } from "next";
import db from "../../app/libs/dbConn";
interface DataProps {
auth: [
{
name?: string;
email?: string;
passwordHash?: string;
}
];
status: number;
message: string;
}
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<DataProps>
) {
if (req.method === "POST") {
const data = {
name: "Gary",
email: `gary@${Math.floor(Math.random() * 9999999)}.subdomain.com`,
passwordHash: "-",
};
const user = await db.user.create({ data });
return res
.status(200)
.json({ auth: [data], status: 201, message: "created user" });
}
if (req.method === "GET") {
const allUsers = await db.user.findMany();
const users = allUsers.map((user) => {
return {
name: user.name || "",
email: user.email || "",
passwordHash: "" || "",
};
});
return res
.status(200)
.json({ auth: users, status: 200, message: "success" });
}
return res.status(404).json({
auth: [{}],
status: 405,
message: "http verb not supported",
});
}
在上面"GET"节,Typescript报告"auth&;因为有一个错误。错误是——类型'{名称:字符串;电子邮件:字符串;passwordHash:字符串;}[]'不能赋值给类型'[{name?: string |未定义;电子邮件?: string |未定义;passwordHash吗?: string |未定义;}]"。目标需要1个元素,但源可能更少。用户。ts(6,3):期望的类型来自属性'auth',它在类型'DataProps'上声明
我不明白我做错了什么。一切看起来都很好,如果我忽略Typescript错误,它就会像设计的那样工作。
我错过了一些我无法解决的问题。
您已经将auth
声明为[ { name?: string; email?: string; passwordHash?: string; }]
-换句话说,它是一个仅包含一个{ name?: string; email?: string; passwordHash?: string; }
元素的单元素元组。但是代码期望的是{ name?: string; email?: string; passwordHash?: string; }[]
——换句话说,是一个包含任意数量的{ name?: string; email?: string; passwordHash?: string; }
元素的数组。因此,将DataProps.auth
更改为{ name?: string; email?: string; passwordHash?: string; }[]
,您的代码应该可以工作。
更多信息,参见TypeScript手册中关于数组和元组的讨论。
更广泛地说,有几种方法可以用来声明类型:- 1-tuple (
[{ name?: string; email?: string; passwordHash?: string; }]
)意味着它总是包含一个元素。这是一个奇怪的选择(如果我只有一件物品,我会直接返回{ name?: string; email?: string; passwordHash?: string }
),但也许你的设计对它有特定的需求。 - 一个数组(
{ name?: string; email?: string; passwordHash?: string }[]
)可以有0、1或无限项。 - 如果你想在一个真实的用户对象上需要所有的属性,但是返回一个空对象来指示错误,你会使用一个联合类型(
({ name: string; email: string; passwordHash: string } | Record<string, never>)[]
)。(Record<string, never>
的解释见这里) - 个人而言,而不是返回一个空对象,我会使整个
auth
属性可选:
或者,更好的做法是使用联合,为成功和错误响应声明不同的类型。这样,TypeScript就不会让我访问属性,除非先检查响应是否成功。像这样利用TypeScript的类型系统可以让代码更容易维护。interface User { name: string; email: string; passwordHash: string; } interface DataProps { auth?: User[]; status: number; message: string; }
interface DataProps { auth: User[]; } interface ErrorResponse { status: number; message: string; error: true; errorDetails?: ErrorDetails; // for example } type SuccessResponse<T> = T & { status: number; message: string; error?: false; } export default async function handler( req: NextApiRequest, res: NextApiResponse<DataProps> ) {