Kodokon kodokon.com

การกำหนด type ให้กับโค้ดในโลกจริง: DOM, fetch, JSON

คงไว้ซึ่ง type ที่เชื่อถือได้ที่ขอบเขตของแอปพลิเคชัน ซึ่งเป็นที่ที่ DOM เครือข่าย และ JSON หลุดพ้นจากคอมไพเลอร์

10 นาที · 3 คำถาม

เปิดบทเรียนนี้ใน Kodokon

โค้ดในโลกจริงเริ่มต้นที่ซึ่ง type อันสมบูรณ์แบบสิ้นสุดลง: DOM เครือข่าย และ JSON คืนข้อมูลที่ TypeScript เดาไม่ได้ พรมแดนแรก: DOM querySelector คืน Element | null ซึ่งเป็น type ที่คลุมเครือเกินกว่าจะอ่าน value หรือเรียก focus()

TYPESCRIPT
const input = document.querySelector<HTMLInputElement>(
  "#email"
);

if (input) {
  input.value = "test@example.com";
  input.focus();
}
type parameter บน querySelector และตัวป้องกันสำหรับ null

type parameter คือคำสัญญาที่คุณให้ไว้กับคอมไพเลอร์: เป็นหน้าที่ของคุณที่จะเล็งไปยัง selector ที่ถูกต้อง เมื่อ element มาจาก event ให้เลือกใช้การตรวจสอบด้วย instanceof ซึ่งตรวจสอบ type ขณะรันไทม์จริง ๆ

TYPESCRIPT
const form = document.querySelector("form");

form?.addEventListener("submit", (event) => {
  event.preventDefault();
  if (event.target instanceof HTMLFormElement) {
    console.log(new FormData(event.target));
  }
});
instanceof ตรวจสอบและทำ type ให้แคบลงในเวลาเดียวกัน

พรมแดนที่สอง: เครือข่าย response.json() คืน Promise<any> หรือกล่าวอีกนัยหนึ่งคือประตูที่เปิดกว้างสู่อะไรก็ได้ ขั้นต่ำในระดับมืออาชีพคือ: ประกาศ type ที่คาดหวังไว้ ตรวจสอบ response.ok และรวมศูนย์การเรียกไว้ในฟังก์ชันที่มี type

TYPESCRIPT
interface Post {
  id: number;
  title: string;
}

async function getPost(id: number): Promise<Post> {
  const url = `https://api.example.com/posts/${id}`;
  const response = await fetch(url);
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}`);
  }
  return (await response.json()) as Post;
}
การเรียก fetch ที่รวมศูนย์และมี type

as Post นั้นยังคงเป็นคำแถลงความไว้วางใจ: หาก API เปลี่ยนไป ไม่มีอะไรเตือนคุณขณะรันไทม์ สำหรับข้อมูลที่สำคัญยิ่ง ให้เขียน type guard ที่ตรวจสอบรูปทรงที่แท้จริงของ JSON ก่อนใช้งานมัน

TYPESCRIPT
function isPost(value: unknown): value is Post {
  if (typeof value !== "object" || value === null) {
    return false;
  }
  const obj = value as Record<string, unknown>;
  return (
    typeof obj.id === "number" &&
    typeof obj.title === "string"
  );
}
type guard ที่ตรวจสอบ JSON ที่ได้รับ (ต่อจากตัวอย่างเดิม)

ทดสอบความรู้

ตรวจสอบว่าคุณจำประเด็นสำคัญของบทเรียนนี้ได้ครบถ้วน

  1. type ที่คืนกลับมาของ response.json() บน response ของ fetch คืออะไร?
    • Promise<unknown>
    • Promise<any>
    • Promise<object>
    • any
  2. ทำไมจึงควรเลือกใช้ event.target instanceof HTMLFormElement มากกว่าการ assert as HTMLFormElement?
    • มันเร็วกว่าขณะรันไทม์
    • instanceof ตรวจสอบ type ขณะรันไทม์จริง ๆ ในขณะที่ as เพียงแค่ทำให้คอมไพเลอร์เงียบ
    • as ถูกห้ามใช้ในโหมด strict
  3. document.querySelector('#email') คืนอะไรเมื่อไม่มี type parameter?
    • HTMLInputElement
    • Element | null
    • HTMLElement
    • null