javascript - เพิกเฉยข้อผิดพลาดของ Typescript "property does not exist on value of type"
ใน VS2013 การสร้างจะหยุดเมื่อ tsc ออกจากโปรแกรมด้วยรหัส 1 ซึ่งไม่ใช่กรณีนี้ใน VS2012
ฉันจะรันโซลูชันของฉันได้อย่างไรในขณะที่ไม่สนใจข้อผิดพลาดของ tsc.exe?
ฉันได้รับข้อผิดพลาด The property 'x' does not exist on value of type 'y' หลายครั้ง ซึ่งฉันต้องการละเว้นเมื่อใช้ฟังก์ชันของ JavaScript
คำตอบ #1
ฉันรู้ว่าคำถามนี้ถูกปิดไปแล้ว แต่ฉันพบมันขณะค้นหาข้อผิดพลาด TypeScriptException แบบเดียวกัน บางทีคนอื่นอาจเจอคำถามนี้ขณะค้นหาปัญหานี้
ปัญหาอยู่ที่การขาดการกำหนดชนิดใน TypeScript:
var coordinates = outerElement[0].getBBox();
ขว้าง คุณสมบัติ 'getBBox' ไม่มีอยู่ในค่าของประเภท 'HTMLElement'
var outerHtmlElement: any = outerElement[0];
var coordinates = outerHtmlElement.getBBox();
แก้ไข, ปลายปี 2016
ตั้งแต่ TypeScript 1.6 ตัวดำเนินการแปลงประเภทที่แนะนำคือ as ดังนั้นบรรทัดเหล่านั้นสามารถรวมเป็น:
let coordinates = (outerElement[0] as any).getBBox();วิธีแก้อื่น ๆ
แน่นอนว่าถ้าคุณอยากทำให้ถูกต้อง ซึ่งบางครั้งก็เกินความจำเป็น คุณสามารถ:
- สร้างอินเทอร์เฟซของตัวเองซึ่งเพียงแค่ขยาย
HTMLElement - แนะนำการพิมพ์ของตัวเองซึ่งขยายจาก
HTMLElement
คำตอบ #2
วิธีแก้ปัญหาแบบง่ายและรวดเร็วคือการแปลงชนิดเป็น any โดยตรง
(y as any).x
“ข้อดี” คือ การทำการแปลงชนิดข้อมูลอย่างชัดเจนนี้ จะสามารถคอมไพล์ได้แม้ว่าจะตั้งค่า noImplicitAny ไว้ก็ตาม
วิธีแก้ปัญหาที่ถูกต้องคือการอัปเดตไฟล์คำนิยามประเภท
โปรดทราบว่า เมื่อคุณทำการแปลงตัวแปรเป็น any คุณจะ ยกเลิกการตรวจสอบประเภท ของตัวแปรนั้น
เนื่องจากฉันอยู่ในโหมดปฏิเสธความรับผิด การแคสต์สองครั้งผ่าน any ร่วมกับอินเทอร์เฟซใหม่ สามารถเป็นประโยชน์ในสถานการณ์ที่
- คุณไม่ต้องการอัปเดตไฟล์ typings ที่เสียหาย
- และ/หรือคุณกําลังปะลิง
อย่างไรก็ตาม คุณยังต้องการรูปแบบการพิมพ์บางอย่างอยู่
สมมติว่าคุณต้องการปรับแก้คำจำกัดความของตัวอย่าง y ที่มีประเภท OrginalDef ด้วยคุณสมบัติใหม่ x ที่มีประเภท number:
// The `y` variable has a typing `OriginalDef` missing a property `x`
const y: OriginalDef = ...
// create an interface with your new property(ies)
interface DefWithNewProperties extends OriginalDef {
x: number
}
// patch the current `y` to the new interface using double casting
const patched = y as any as DefWithNewProperties
// the patched value can now access the new property
// the type inference and type checker will work correctly
patched.x = .... //will compile
คำตอบ #3
คุณสามารถใช้เคล็ดลับต่อไปนี้ได้เช่นกัน:
y.x = "some custom property"//gives typescript errory["x"] = "some custom property"//no errorsโปรดทราบว่า เพื่อเข้าถึง x และไม่ให้เกิดข้อผิดพลาดของ TypeScript อีกครั้ง คุณต้องเขียนแบบนี้ y["x"] ไม่ใช่ y.x ดังนั้นจากมุมมองนี้ ตัวเลือกอื่น ๆ จะดีกว่า
คำตอบ #4
มีหลายวิธีในการจัดการปัญหานี้ หากวัตถุนี้เกี่ยวข้องกับไลบรารีภายนอกบางตัว วิธีแก้ปัญหาที่ดีที่สุดคือต้องหาผลไฟล์นิยามที่แท้จริง (มีที่เก็บที่ดีที่นี่) สำหรับไลบรารีนั้นและอ้างอิงมัน เช่น:
/// <reference path="/path/to/jquery.d.ts" >
แน่นอน สิ่งนี้ไม่ได้ใช้กับหลายกรณี
ถ้าคุณต้องการ 'แทนที่' ระบบประเภท ลองทำตามนี้:
declare var y;
นี่จะช่วยให้คุณสามารถโทรออกได้ทุกสายที่คุณต้องการบน var y
คำตอบ #5
ฉันรู้ว่าตอนนี้เป็นปี 2020 แต่ฉันไม่สามารถเห็นคำตอบที่ตอบสนองส่วน 'ignore' ของคำถามได้ ปรากฏว่าคุณสามารถบอก TSLint ให้ทำเช่นนั้นได้โดยใช้ directive
// @ts-ignore
this.x = this.x.filter(x => x.someProp !== false);
โดยปกติสิ่งนี้จะทำให้เกิดข้อผิดพลาด โดยจะบอกว่า 'someProp ไม่มีอยู่ในประเภท' แต่เมื่อมีคอมเมนต์ ข้อผิดพลาดนั้นก็หายไป
นี่จะหยุดไม่ให้เกิดข้อผิดพลาดใด ๆ เมื่อทำการคอมไพล์ และน่าจะหยุดไม่ให้ IDE ของคุณบ่นใส่คุณด้วย
คำตอบ #6
เมื่อ TypeScript คิดว่าคุณสมบัติ "x" ไม่มีอยู่ใน "y" คุณสามารถแปลงชนิดของ "y" เป็น "any" ซึ่งจะช่วยให้คุณสามารถเรียกใช้อะไรก็ได้ (เช่น "x") บน "y".
ทฤษฎี
(<any>y).x;
ตัวอย่างในโลกจริง
ฉันได้รับข้อผิดพลาด "TS2339: Property 'name' does not exist on type 'Function'" สำหรับโค้ดนี้:
let name: string = this.constructor.name;
ดังนั้นฉันจึงแก้ไขมันด้วย:
let name: string = (<any>this).constructor.name;
คำตอบ #7
มีปัญหาใน Angular2 ฉันกำลังใช้ local storage เพื่อบันทึกบางอย่างแต่มันไม่ยอมให้ฉันทำ
วิธีแก้ปัญหา:
ฉันมี localStorage.city -> error -> Property 'city' ไม่มีอยู่ในชนิด 'Storage'.
วิธีแก้ไข:
localStorage['city']
(localStorage).city
(localStorage เป็น any).city
