วิธีที่สะอาดที่สุดในการบอก 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]++;
});
