reactjs - Notion API ger ett fel för typen kandidat


Koden som orsakar problemet är koden nedan

import {Client, LogLevel} from "@notionhq/client";

const notion = new Client({
    auth: process.env.NOTION_TOKEN,
    logLevel: process.env.NODE_ENV !== 'production' ? LogLevel.DEBUG : undefined
});

export const getPage = async (pageId:string) => {
    const response = await notion.pages.retrieve({ page_id: pageId });

    // ↓ Error this Line !!!
    const pageTitle = response.properties.Name.title[0].plain_text;
    console.log(pageTitle);
    return response;
};

När jag använder Notion-API:et för att hämta block får jag ett fel som det ovan och kan inte få egenskapen korrekt. Typen behandlas som any, vilket orsakar ett fel i redigeraren, men kan hämtas korrekt i webbläsaren.

Hur kan jag bli av med felet i redigeraren?

Det här problemet kan också vara ett problem med redigeraren eller TypeScript. Ge mig gärna några tips 🙇️.

Tack för att du svarade innan jag gjorde!

Property 'properties' does not exist on type 'GetPageResponse'.
  Property 'properties' does not exist on type '{ object: "page"; id: string; }'.ts(2339)

Huvudmiljön ser ut så här

// package.json

{
  "name": "notion-api-test",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",
    "typelint": "tsc --noEmit"
  },
  "dependencies": {
    "@chakra-ui/icons": "^1.1.1",
    "@chakra-ui/react": "^1.7.4",
    "@emotion/react": "^11.7.1",
    "@emotion/styled": "^11.6.0",
    "@notionhq/client": "^0.4.12",
    "firebase": "^9.6.3",
    "framer-motion": "^5.6.0",
    "next": "12.0.8",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "recoil": "^0.5.2",
    "swr": "^1.1.2"
  },
  "devDependencies": {
    "@types/node": "^17.0.9",
    "@types/react": "^17.0.38",
    "@typescript-eslint/eslint-plugin": "^5.10.0",
    "@typescript-eslint/parser": "^5.10.0",
    "eslint": "8.7.0",
    "eslint-config-next": "12.0.8",
    "eslint-plugin-react": "^7.28.0",
    "eslint-plugin-react-hooks": "^4.3.0",
    "focus-visible": "^5.2.0",
    "prettier": "^2.5.1",
    "typescript": "^4.5.4"
  }
}

// vscode

Version: 1.63.2
Commit: 899d46d82c4c95423fb7e10e68eba52050e30ba3
Date: 2021-12-15T09:38:17.605Z
Electron: 13.5.2
Chromium: 91.0.4472.164
Node.js: 14.16.0
V8: 9.1.269.39-electron.0
OS: Darwin arm64 21.1.0
node --version
v16.8.0

Svar #1

Här är en typdefinition av GetPageResponse från node_modules\@notionhq\client\build\src\api-endpoints.d.ts:

export declare type GetPageResponse = {
    parent: {
        type: "database_id";
        database_id: IdRequest;
    } | {
        type: "page_id";
        page_id: IdRequest;
    } | {
        type: "workspace";
        workspace: true;
    };
    properties: Record<string, {
        type: "title";
        title: Array<{
           ...

Vid första anblick kan du se att det har properties: Record<string, {...}>, så vad är problemet, eller hur?

Problemet är att det bara finns i en av de två möjliga definitionerna av den typen. Se denna förenklade version:

export declare type GetPageResponse = {
    parent: {/*...*/};
    properties: Record<string, {/*...*/}>;
    /* ... */
} | {
    object: "page";
    id: string;
};

Som du kan se kan GetPageResponse också vara av typen { object: "page"; id: string; }, och denna typ har inte properties.

Så, du måste först se till att egendomen finns, på det här sättet:

if ("properties" in response) {
  const pageTitle = response.properties.Name.title[0].plain_text;
  console.log(pageTitle);
  return response;
}

Fullständig kompilerande kod kan se ut så här:

import { Client, LogLevel } from "@notionhq/client";

const notion = new Client({
  auth: process.env.NOTION_TOKEN,
  logLevel: process.env.NODE_ENV !== "production" ? LogLevel.DEBUG : undefined,
});

export const getPage = async (pageId: string) => {
  const response = await notion.pages.retrieve({ page_id: pageId });

  if ("properties" in response) {
    if ("title" in response.properties.Name) {
      const pageTitle = response.properties.Name.title[0].plain_text;
      console.log(pageTitle);
      return response;
    }
  }
};