TypeScript中实例对象无法访问动态添加方法问题求助
解决TypeScript中动态添加类方法的类型提示问题
TypeScript是静态类型语言,编译器只会识别你在类中显式声明的成员,你通过init方法动态添加的red、blue等方法,默认不会被静态检查识别,因此编辑器会提示属性不存在。另外你的代码还有两处细节问题:consol拼写错误应为console,且实例化后未调用init方法——就算类型问题解决,运行时也会报错。
下面给出三种可行的解决方式:
方案一:定义接口并实现
先创建包含所有颜色方法的接口,让Chalk类实现该接口,同时用非空断言!告诉TypeScript这些方法会在init中初始化:
// 定义所有颜色方法的接口 interface ChalkColorMethods { black: () => void; blue: () => void; cyan: () => void; gray: () => void; green: () => void; magenta: () => void; red: () => void; white: () => void; yellow: () => void; } class Chalk implements ChalkColorMethods { // 用!断言属性会被初始化,避免TS报错 black!: () => void; blue!: () => void; cyan!: () => void; gray!: () => void; green!: () => void; magenta!: () => void; red!: () => void; white!: () => void; yellow!: () => void; public init(): void { const colors = ['black', 'blue', 'cyan', 'gray', 'green', 'magenta', 'red', 'white', 'yellow'] as const; for (let color of colors) { this[color] = () => { console.log(color) }; } } }; const chalk = new Chalk(); chalk.init(); // 必须调用初始化方法 chalk.red(); // 编辑器无提示错误,运行正常
方案二:使用索引签名
如果不想逐个声明方法,可以给类添加索引签名,允许任意字符串属性对应无参数函数,这种方式更灵活但类型提示稍弱:
class Chalk { // 索引签名:任意字符串key对应() => void类型的函数,允许未定义 [key: string]: (() => void) | undefined; public init(): void { const colors = ['black', 'blue', 'cyan', 'gray', 'green', 'magenta', 'red', 'white', 'yellow']; for (let color of colors) { this[color] = () => { console.log(color) }; } } }; const chalk = new Chalk(); chalk.init(); chalk.red(); // 编辑器无提示错误
方案三:用declare声明成员
在类内部用declare关键字告诉TypeScript动态成员的存在,无需显式定义属性:
class Chalk { // 声明动态添加的方法类型 declare black: () => void; declare blue: () => void; declare cyan: () => void; declare gray: () => void; declare green: () => void; declare magenta: () => void; declare red: () => void; declare white: () => void; declare yellow: () => void; public init(): void { const colors = ['black', 'blue', 'cyan', 'gray', 'green', 'magenta', 'red', 'white', 'yellow'] as const; for (let color of colors) { this[color] = () => { console.log(color) }; } } }; const chalk = new Chalk(); chalk.init(); chalk.red(); // 正常识别方法
内容的提问来源于stack exchange,提问作者Poison
相关产品推荐
相关产品推荐

