报错原文ERROR: 10505001 ArkTS Compiler Error Error Message: Property fn does not exist on type object. At File: xxx.ets:N:N常伴生报错Error Message: Object literal must correspond to some explicitly declared class or interface (arkts-no-untyped-obj-literals)报错触发场景你写鸿蒙 ArkTS 时用object类型装函数成员就炸// ❌ 报错写法 State obj: object { fn: (x: number): number x * 2 } const calc: object { double: (x: number): number x * 2 } const result obj.fn(42) ← Property fn does not exist on type object根因鸿蒙 ArkTS 的object是基类类型——只含toString/hasOwnProperty等基类方法不含任何业务属性。编译器拒绝在object上访问未定义的属性fn/double等。这跟前端 TS 最大的差异TS 里object装任意对象字面量能动态加属性访问ArkTS 里object严守基类契约加属性就报错。ArkTS 这么设计的原因编译期消除一切歧义——object装函数成员是「动态形状」编译器分析不了要求显式interface/ 函数类型 /type别名定义形状编译期就能检查类型安全。真解法三种替代方案按场景选解法 1interface 显式定义函数成员最常用// ✅ 正解 1interface 显式定义函数成员替代 object interface Calculator { fn: (x: number) number } const calc: Calculator { fn: (x: number): number x * 2 } as Calculator const result calc.fn(42) ← 编译过Calculator 有 fn 属性interface 显式定义对象形状——编译器知道Calculator有fn属性访问不报错。解法 2直接标函数类型// ✅ 正解 2直接标函数类型替代 object const double: (x: number) number (x: number): number x * 3 const result double(42) ← 编译过double 是函数类型可调直接标(x: number) number函数类型——不用包对象直接变量装函数。解法 3type 别名标函数类型// ✅ 正解 3type 别名标函数类型替代 objecttype 必须顶层定义 type Predicate (x: number) boolean const isBig: Predicate (x: number): boolean x 10 const result isBig(42) ← 编译过Predicate 是函数类型可调type别名给函数类型起名——复用方便。注意type必须顶层定义不能嵌套在 struct 里。高频踩坑场景场景 1State obj: object装回调// ❌ 报错 State handler: object { onClick: () { ... } } // ✅ 正解interface 定义 interface Handler { onClick: () void } State handler: Handler { onClick: () { ... } } as Handler场景 2object装策略对象// ❌ 报错 const strategies: object { add: (a: number, b: number): number a b, sub: (a: number, b: number): number a - b } const result strategies.add(1, 2) // ✅ 正解interface 定义 interface Strategies { add: (a: number, b: number) number sub: (a: number, b: number) number } const strategies: Strategies { add: (a: number, b: number): number a b, sub: (a: number, b: number): number a - b } as Strategies const result strategies.add(1, 2)场景 3API 回传object你接// ❌ 报错接 API 回传 object访问属性炸 const res: object await someApi() const name res.data.name ← Property data does not exist on type object // ✅ 正解显式 interface 接 interface ApiResponse { data: { name: string } } const res: ApiResponse await someApi() as ApiResponse const name res.data.name场景 4type嵌套在 struct 里// ❌ 报错type 不能嵌套在 struct 里 Component struct Index { type Predicate (x: number) boolean ← 报错 } // ✅ 正解type 顶层定义 type Predicate (x: number) boolean Component struct Index { pred: Predicate (x: number): boolean x 10 }一句话速查Property does not exist on type ‘object’ → object 不能装业务属性用 interface / 函数类型 / type 别名替代跟前端 TS 的差异写法TSArkTSconst x: object { fn: () 1 }✅❌ 报错const x: { fn: () number } { fn: () 1 }✅✅const x: interface { fn: () 1 } as interface✅✅const fn: () number () 1✅✅前端转鸿蒙最容易踩这个坑——TS 里object装任意对象字面量能动态加属性访问ArkTS 里object严守基类契约。新项目从一开始就养成「禁用 object 装业务属性显式 interface / 函数类型」的习惯避坑。object 三种替代速查表替代方案适用场景写法示例interface对象含函数成员interface C { fn: (x: number) number }直接函数类型单函数变量const fn: (x: number) number ...type 别名函数类型复用type Pred (x: number) boolean顶层定义铁律ArkTS 里object只当基类用——装业务属性就 interface / 函数类型 / type别想裸 object。完整代码仓库本文所有正解写法都已托管到AtomGit仓库地址https://atomgit.com/JaneConan/arkui-bug-object-not-callable仓库包含四种高频踩坑场景的 ❌ 报错写法 ✅ 正解写法对照interface / 直接函数类型 / type 别名三种替代方案示范可直接用 DevEco Studio 打开参考作者JaneConan 仓库https://atomgit.com/JaneConan/arkui-bug-object-not-callable 协议Apache-2.0随便用别告我