ค้นหาเว็บไซต์

วิธีที่สะอาดที่สุดในการบอก TypeScript ว่าแต่ละองค์ประกอบของ Object.keys(foo) จริง ๆ แล้วคือคีย์ของ foo คืออะไร?


สนามเด็กเล่น

const foo = {
  a: 1,
  b: 2,
  c: 3
};

Object.keys(foo).forEach(key => {
  foo[key]++; // error: expression of type 'string' can't be used to index ....
})

ต้องมีหลายวิธีในการแก้มัน ฉันกำลังมองหาวิธีที่แนะนำซึ่งมีผลกระทบต่อความอ่านง่ายน้อยที่สุด ขอบคุณ!

==========

แก้ไข :

โบนัส: คงจะดีถ้าฉันยังสามารถมีการเติมข้อความอัตโนมัติเมื่อฉันพิมพ์ foo. ในฐานรหัสของฉัน

คำตอบ #1

นี่ควรจะใช้ได้:

(Object.keys(foo) as (keyof typeof foo)[]).forEach(key => {
    foo[key]++;
})

สิ่งนี้ไม่ได้ทำให้โดยอัตโนมัติสำหรับคุณ เพราะตามทฤษฎีมันอาจไม่ปลอดภัย แต่ฉันได้ลองเล่นกับสถานการณ์ต่าง ๆ และไม่สามารถสร้างตัวอย่างที่ใช้งานได้พร้อมข้อผิดพลาดเวลาเรียกใช้งาน

คำตอบ #2

TypeScript ไม่ได้ให้วิธีใดในการแสดงสิ่งนี้ในเวลาที่ประกาศ foo เพราะว่าอาจมีคนเพิ่มคุณสมบัติเพิ่มเติมให้กับ foo ในภายหลัง เช่น โดยการ:

let o: any;
o = foo;
o.x = 'hello';

จากนั้น Object.keys(foo) จะส่งคืน x ด้วย แต่การพยายามเพิ่ม 'hello' อาจไม่ใช่สิ่งที่คุณตั้งใจ ...

โดยทั่วไปแล้ว ใน TypeScript วัตถุอาจมีคุณสมบัติเพิ่มเติมเสมอ เพราะนี่คือสิ่งที่อนุญาตให้คุณทำ:

interface Person = {
    name: string;
}

interface Student extends Person {
    university: string;
}

let student: Student = ...;
let person: Person = student;

นั่นคือ TypeScript ไม่มีทางแน่ใจได้ว่า Object จะไม่มีคุณสมบัติเกินมา และนั่นเป็นเหตุผลที่ Object.keys ส่งค่ากลับเป็น Array<string> แทนที่จะเป็น Array<keyof typeof foo>

ในกรณีของคุณ ฉันอาจทำดังนี้:

const fooKeys = Object.keys(foo) as Array<keyof typeof foo>;

ทันทีหลังจากประกาศ foo ด้วยวิธีนี้ เราจะถ่ายภาพของคีย์ที่เราตั้งใจจะวนซ้ำก่อนที่ใครก็ตามจะมีโอกาสแก้ไขมัน จากนั้นคุณสามารถทำได้ดังนี้:

fooKeys.forEach(key => {
    foo[key]++;
});

บทความที่เกี่ยวข้อง