添加TypeScript支持
import { json } from "@remix-run/node";
import { Link, useLoaderData } from "@remix-run/react";
type Post = {
slug: string;
title: string;
};
type LoaderData = {
posts: Array<Post>;
};
export const loader = async () => {
return json<LoaderData>({
posts: [
{
slug: "my-first-post",
title: "My First Post",
},
{
slug: "90s-mixtape",
title: "A Mixtape I Made Just For You",
},
],
});
};
export default function Posts() {
const { posts } = useLoaderData() as LoaderData;
return (
<main>
<h1>Posts</h1>
<ul>
{posts.map((post) => (
<li key={post.slug}>
<Link
to={post.slug}
className="text-blue-600 underline"
>
{post.title}
</Link>
</li>
))}
</ul>
</main>
);
}
在json里添加了一个LoaderData的接口
这部分Ts还是比较简单的,有兴趣自己查查
但是如果在useLoaderData后边不设置 as LoaderData就会出现any类型
所以我们在读取数据的时候又设置了一下any
补充
在loader里的json函数是为了在响应数据的时候创建一个application/json头,并假定你使用了utf-8编码
关于这部分可以参考代码
const json = (data, init = {}) => {
let responseInit = typeof init === "number" ? {
status: init
} : init;
let headers = new Headers(responseInit.headers);
if (!headers.has("Content-Type")) {
headers.set("Content-Type", "application/json; charset=utf-8");
}
return new Response(JSON.stringify(data), { ...responseInit,
headers
});
};
补充完毕
当设置好TS类型后,即使通过网络请求读取数据,也可以获得类型的安全性,因为在同一个文件定义,除非在读取数据的时候崩溃,否则在组件和API中都具有类型安全性。
一点点的重构
一个可靠的办法就是创建一个处理特定问题的模块,在例子中,将阅读和攥写帖子,现在让我们新建一个模块,然后增加getPosts函数,并将他导出
创建app/models/post.server.ts
粘贴内容
type Post = {
slug: string;
title: string;
};
export async function getPosts(): Promise<Array<Post>> {
return [
{
slug: "my-first-post",
title: "My First Post",
},
{
slug: "90s-mixtape",
title: "A Mixtape I Made Just For You",
},
];
}
这里虽然没有使用任何异步,但是使用了async,说明以后你可以在这里使用
因为async返回Promise,所以类型提示是
Promise<Array<Post>>
接下来在
app\routes\posts\index.tsx
更新代码为
import { getPosts } from "~/models/post.server";
type LoaderData = {
// this is a handy way to say: "posts is whatever type getPosts resolves to"
posts: Awaited<ReturnType<typeof getPosts>>;
};
export const loader = async () => {
return json<LoaderData>({
posts: await getPosts(),
});
};
这里的
Awaited<ReturnType<typeof getPosts>>
算是一个难点
getPosts是一个函数
首席按typeof获取他的类型
得到
()=>Promise<Post[]>
然后使用ReturnType得到一个函数的返回类型推断
也就是Promise<Post[]>
Awaited类似于await,会递归取得嵌套在promise的类型
可以参考https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-5.html
也就是说最后得到了Post[]作为返回类型
那么说白了
type LoaderData = {
// this is a handy way to say: "posts is whatever type getPosts resolves to"
posts: Awaited<ReturnType<typeof getPosts>>;
};
这段代码
也就是
type LoaderData = {
posts: Post[];
};
罢了
那官方课程第一篇的一半已经结束后,后续涉及Prisma~
结语
撒花~