Notion公式ライブラリで取得したデータのプロパティがサジェストで全部出てこずにエラー出す問題の解決
読み飛ばしてすぐに5個目のコメント見てください
import { Client } from "@notionhq/client";
const NotionClient = new Client({auth: process.env.NOTION_SECRET as string})
export default NotionClient
import Notionclient from "@/client/notion";
export default function NotionPage(){
Notionclient.databases.query({
database_id: process.env.DATABASE_ID as string,
"sorts":[
{
property: "~~",
direction: "descending"
}
]
}).then((res)=> {
for(let i in res.results){
console.log(res.results[0])
}
})
return (<p>TEST</p>)
}
このとき、res.results[0]
のプロパティは、id
とobject
しか持っていない状態になっている。しかし、console.log(res.results[0])
を実行すると、より多くのプロパティが出現する。つまり、実際に返ってくるデータとデータの型定義が矛盾していることがわかる。
ライブラリの中身こんな感じにいじる
・・・
export type QueryDatabaseResponse = {
type: "page";
page: EmptyObject;
object: "list";
next_cursor: string | null;
has_more: boolean;
results: Array<PageObjectResponse>;
}
・・・
何をしているかというと、results
の定義である、Array<PageObjectResponse | PartialPageObjectResponse>
の| PartialPageObjectResponse
を消去する
これをすると、プロパティがしっかり全部出てくる
代替案、ご指摘等あれば遠慮なくこのスクラップに投稿してください!!
以下のように「PageObjectResponse
には存在して PartialPageObjectResponse
には存在しないプロパティ」があることを if
を使ってチェックすることで、PageObjectResponse
のプロパティにアクセスできるようになります。
export default function NotionPage(){
Notionclient.databases.query({
//...
}).then((res)=> {
res.results.forEach(result => {
if ("properties" in result){
// 以降は型が PageObjectResponse に限定される
console.log(result.url)
}
})
})
return (<p>TEST</p>)
}
これはどのクエリでも同様で、blocks.children.list()
でページの中身を取得した場合も以下のようにプロパティをチェックして PartialBlockObjectResponse
の型を弾くことになります。
await notion.blocks.children.list({block_id: id}).then(res => {
res.results.forEach(block => {
if ("type" in block){ // type の存在をチェックしないと .type へのアクセスが型エラーになる
if (block.type=="heading_1") { /*...*/ }
else if (block.type=="paragraph") { /*...*/ }
}
})
})
Notion API の型は、他にも~~Response
型のオブジェクトが~~Request
型のオブジェクトとして使えないことがあるなど厄介な部分が多いので、真面目に動かすのは結構大変です。
なるほど、取得したデータを条件分岐で中身を調べることによって型を確定させるのですね!
アドバイスありがとうございます!やってみます!!
暇があったら試してみます