如何解决访问函数属性时出现的TypeScript类型错误?
解决TypeScript中函数添加自定义属性的类型错误
你遇到的问题是因为TypeScript默认把foo推断为() => void类型,这个类型没有定义prop属性,所以直接访问foo['prop']会触发类型错误。下面是几种靠谱的解决方式:
1. 定义包含函数签名的接口(最规范)
先声明一个接口,同时包含函数的调用签名和prop属性,然后把foo指定为这个接口类型:
interface FooFunc { (): void; prop?: { some: () => void } | null; } const foo: FooFunc = function() { if (foo.prop && typeof foo.prop.some === 'function') { foo.prop.some(); } }; // 外部赋值也能正常类型检查 foo.prop = { some: () => console.log('called') }; foo.prop = null;
这种方式能让TypeScript完全识别foo的函数身份和额外属性,还能对prop的类型做严格约束,是最推荐的写法。
2. 直接给函数添加类型断言(快速解决)
如果不想写接口,也可以在访问prop时用类型断言告诉TypeScript它的类型:
function foo() { // 断言foo包含可选的prop属性 const prop = (foo as { prop?: { some: () => void } | null }).prop; if (prop && typeof prop.some === 'function') { prop.some(); } } foo.prop = { some: () => {} }; foo.prop = null;
这种方式更简洁,但类型约束的严谨性不如接口方案,适合快速修复小场景。
3. 用Object.assign创建带属性的函数
通过Object.assign可以让TypeScript自动推断出函数带有额外属性:
const foo = Object.assign(function() { if (foo.prop && typeof foo.prop.some === 'function') { foo.prop.some(); } }, { // 初始化prop,也可以留空后续赋值 prop: null as { some: () => void } | null }); foo.prop = { some: () => {} };
这种方式不需要手动写接口,TS会根据Object.assign的参数自动合并类型,也比较灵活。
为什么'prop' in foo没用?
因为TypeScript默认的函数类型() => void并没有包含prop的定义,即便用'prop' in foo确认了属性存在,TS还是无法确定prop的具体类型,所以需要手动给函数补充类型定义,才能让类型检查生效。
内容的提问来源于stack exchange,提问作者Jon Sud
相关产品推荐
相关产品推荐

