วิธีพิมพ์ฟังก์ชัน JavaScript ด้วย JSDoc + TypeScript?
อัปเดต (2023)
ฉันจริงๆ แล้วได้พูดในการบรรยายเกี่ยวกับวิธีการใช้ tsc + JSDoc ที่ตอบคำถามนี้และอีกหลายคำถาม:
- https://jswithtypes.com
และสร้างแพ็กเกจเพื่อช่วยกับโค้ดพื้นฐานของ tsconfig:
https://npmjs.org/jswt
npx jswt init
คำถามต้นฉบับ
ฉันกำลังพยายามใช้ tsc กับ JavaScript ธรรมดาและฉันงงว่าต้องประกาศชนิดของฟังก์ชันอย่างไร
ดูเหมือนว่ามันควรง่ายเพียงแค่นี้:
/** @type PersonGreet */
person.greet = function greet(other) {
return `Hello ${other.name}, my name is ${person.name}!`;
};
แก้ไข: /** @type PersonGreet */ ถูกต้อง พฤติกรรมปัจจุบันเป็นข้อบกพร่องใน tsc คำตอบที่เลือกด้านล่างให้วิธีแก้ไขที่ถูกต้อง
กรณีทดสอบที่ลดลง
ละเว้นความจริงที่ว่าอาจมีใครบางคนต้องการปรับโครงสร้างใหม่นี้โดยใช้คลาสหรือโพรโทไทป์หรืออะไรทำนองนั้น - มันก็ทำหน้าที่ได้ดีในฐานะตัวอย่างของปัญหา
รีโพ: https://github.com/BeyondCodeBootcamp/hello-tsc
"use strict";
/**
* @typedef {Object} Person
* @property {String} name
* @property {PersonGreet} greet
*/
/**
* @typedef {Function} PersonGreet
* @param {Person} other
* @returns {String}
*/
let Person = {};
/**
* Creates a person
* @param {Object} p
* @param {String} p.name
* @returns {Person}
*/
Person.create = function (p) {
let person = {};
person.name = p.name;
/////////////////////////////////////////////////////////////////////////////////
//
// error TS7006: Parameter 'other' implicitly has an 'any' type. <======= WRONG!
//
/////////////////////////////////////////////////////////////////////////////////
/** @type PersonGreet */
person.greet = function greet(other) {
return `Hello ${other.name}, my name is ${person.name}!`;
};
return person;
};
module.exports = Person;
พิมพ์ผิดเป็น 'any'
เมื่อฉันรัน tsc เพื่อเช็ค มันจะแสดงข้อผิดพลาดเกี่ยวกับ implicit any:
tsc -p jsconfig.json
person.js:28:33 - error TS7006: Parameter 'other' implicitly has an 'any' type.
28 person.greet = function greet(other) {
~~~~~
Found 1 error in person.js:28
ทำอย่างไรดี?
สำหรับฉัน สิ่งนี้ดูเหมือนเป็นบั๊กใน tsc... แต่สิ่งนี้เป็นเรื่องพื้นฐานของ JS 101 แน่นอนว่าต้องมีวิธีในการกำหนดประเภทให้ฟังก์ชันใช่ไหม?
ฉันต้องใช้คำอธิบายประกอบอะไรในการประกาศประเภทของฟังก์ชัน? หรือว่า tsc/tsserver/typescript ไม่สามารถจัดการกับการใช้งานพื้นฐานแบบนี้ของ JS ได้เลย?
คำตอบ #1
วิธีแก้ปัญหา 1
คุณควรใช้ @callback แทน @function ดังนี้:
"use strict";
/**
* @typedef {Object} Person
* @property {String} name
* @property {PersonGreet} greet
*/
/**
* @callback PersonGreet
* @param {Person} other
* @returns {String}
*/
let Person = {};
/**
* Creates a person
* @param {Object} p
* @param {String} p.name
* @returns {Person}
*/
Person.create = function (p) {
let person = {};
person.name = p.name;
/** @type {PersonGreet} */
person.greet = function greet(other) {
return `Hello ${other.name}, my name is ${person.name}!`;
};
return person;
};
module.exports = Person;
วิธีแก้ปัญหา 2
หรือ ประกาศ @typedef โดยใช้ไวยากรณ์ของ TypeScript ดังต่อไปนี้:
/**
* @typedef {(other: Person) => string} PersonGreet
*/
