收藏
回答

使用typescript开发behavior,调用data 的数据过不了类型检测怎么办?

1、创建一个behavior,并在组件中引入这个behavior,调用behavior里的data和方法 都会报错不存在该属性或者方法;虽然是可以用as any 就可以调用到,但是有没有更好的解决方法呢?

2、在组件中引入这个behavior,调用behavior里的data和方法 都会报错不存在该属性或者方法;

回答关注问题邀请回答
收藏

17 个回答

  • niniyou
    niniyou
    2022-08-29
    declare namespace WechatMiniprogram.Page {
      interface ILifetime {
        test():void;
      }
    }
    declare namespace WechatMiniprogram.Component {
      interface InstanceMethods<D extends DataOption> {
        test(): void;
      }
    }
    

    可以尝试在类型声明中typings/index.d.ts进行声明类型扩展,应该会有用

    2022-08-29
    有用 2
    回复 1
    • Damon
      Damon
      2023-02-21
      不错
      2023-02-21
      回复
  • 👾👾👾👾👾
    👾👾👾👾👾
    2024-08-22

    2020年的问题,现在2024年了,有什么完美解法吗?

    2024-08-22
    有用 1
    回复 3
    • 李浩然
      李浩然
      2024-08-27
      蹲一下
      2024-08-27
      回复
    • 尹joy
      尹joy
      2024-12-06
      可以看下当前页面我的方案
      2024-12-06
      回复
    • 尹joy
      尹joy
      2024-12-06回复李浩然
      看看我的
      2024-12-06
      回复
  • 不吱
    不吱
    2021-05-27

    同求解……我每次都要 (this as any).test() ,但这样看起来很拉跨

    2021-05-27
    有用 1
    回复
  • 尹joy
    尹joy
    2024-12-05

    只需要定义behavior的同时能自动导出对应的behavior类型,在page或者component的property/data/methods中定义一个空对象并强制类型为behavior对应的property/data/methods类型即可。

    // 组件或者页面的定义文件
    import listBehavior, { type ListBehavior } from '@/behaviors/listBehavior'
    type Item = { id: string; num: number }
    Component({
        behaviors: [listBehavior],
        properties: {
            ...{} as ListBehavior<Item[]>['properties'],
            otherProp: {
                type: String,
                value: '0'
            }
        },
        data: {
            ...{} as ListBehavior<Item[]>['data'],
        },
        methods: {
            ...{} as ListBehavior<Item[]>['methods'],
            getList(page, pageSize) {
                return doReq('/getAllList', page, pageSize)
            }
            onPullDownRefresh() {
                // listBehavior['methods']中的refreshList
                this.refreshList()
            },
            onReachBottom() {
                // listBehavior['methods']中的loadList
                this.loadList()
            }
        }
    })
    


    // behaviors/listBehavior.ts
    import { useBehavior } from '@/utils/use'
    const {
        behaviorID,
        _optType,
    } = useBehavior({
        data: {
            list: [],
            _page: 1,
            _pageSize: 10,
        },
        methods: {
            loadList() {
                // 此处的getList是使用behavior的组件或者页面中定义的
                this.getList(this.data._page, this.data._pageSize).then(res => {
                    this.setData({
                        list: res
                    })
                })
            },
            refreshList() {
                this.setData({
                    _page: 1,
                    list: []
                })
                this.loadList()
            }
        }
    })
    export default behaviorID
    export type ListBehavior = typeof _optType
    


    核心就在于定义behavior的同时能够导出一个能表示当前类型的变量_optType,_optType可以是没有任何实际作用的空对象{},它的作用就是能够通过 typeof 来实现自动导出behavior类型。

    这个解决方案无任何副作用,校验完备,使用简便。

    2024-12-05
    有用
    回复 5
    • 梦游
      梦游
      2024-12-18
      这个_optType能根据behavior传的参数自动推导出来吗,是说要要自己手写一个空对象然后断言,我看behavior返回的是一个字符串,貌似没办法推导类型了
      2024-12-18
      回复
    • 尹joy
      尹joy
      2024-12-18回复梦游
      需要写个工具,导出behavior id标识时导出并断言一个空对象为定义behavior时的data,methods,property等入参。你可以参考我的实现
      2024-12-18
      1
      回复
    • 梦游
      梦游
      2024-12-19回复尹joy
      实测发现,method的类型是可选类型,在扩展到页面里直接this.去访问会ts报错可能是undefined,看了一下d.ts里的类型也没问题啊,是怎么回事呢,
      2024-12-19
      回复
    • 梦游
      梦游
      2024-12-19回复尹joy
      我把这个method的可选范型改成非空就好了,但是小程序的类型声明文件里确实是可选的
      2024-12-19
      回复
    • 尹joy
      尹joy
      2024-12-20回复梦游
      你把代码贴全一点,我这边试的都正常,不管是在Component,Page,或是在其他behavior的构造方法里。
      2024-12-20
      回复
  • 李浩然
    李浩然
    2024-08-27

    我修改了类型文件中 `WechatMiniprogram.Page.Constructor` 的和 `Options` 类型的定义. 添加了两个新的可选范型 `BehaviorData` 和 `BehaviorMethods`. 在使用 `Page` 的时候把相应的 behavior 的类型传进去.

    type Options<
      TData extends DataOption,
      TCustom extends CustomOption,
      BehaviorData,
      BehaviorMthods
    > = (TCustom &
      Partial<Data<TData>> &
      Partial<ILifetime> & {
        options?: Component.ComponentOptions
      }) &
      ThisType<Instance<TData & BehaviorData, TCustom & BehaviorMthods>>
    
    
    interface Constructor {
      <TData extends DataOption, TCustom extends CustomOption, BehaviorData = {}, BehaviorMethods = {}>(
        options: Options<TData, TCustom, BehaviorData, BehaviorMethods>
      ): void
    }
    
    Page<TData, TOptions, BehaviorData, BehaviorMethods>({
      behaviors: [behavior],
      ...
    })
    


    暂时可以解决这个问题.

    2024-08-27
    有用
    回复
  • 李浩然
    李浩然
    2024-08-27

    我修改了类型文件中 `WechatMiniprogram.Page.Constructor` 的和 `Options` 类型的定义. 添加了两个新的可选范型 `BehaviorData` 和 `BehaviorMethods`. 在使用 `Page` 的时候把相应的 behavior 的类型传进去.

    type Options<
      TData extends DataOption,
      TCustom extends CustomOption,
      BehaviorData,
      BehaviorMthods
    > = (TCustom &
      Partial<Data<TData>> &
      Partial<ILifetime> & {
        options?: Component.ComponentOptions
      }) &
      ThisType<Instance<TData & BehaviorData, TCustom & BehaviorMthods>>
    
    
    interface Constructor {
      <TData extends DataOption, TCustom extends CustomOption, BehaviorData = {}, BehaviorMethods = {}>(
        options: Options<TData, TCustom, BehaviorData, BehaviorMethods>
      ): void
    }
    
    Page<TData, TOptions, BehaviorData, BehaviorMethods>({
      behaviors: [behavior],
      ...
    })
      
    


    暂时可以解决这个问题.

    2024-08-27
    有用
    回复
  • 李浩然
    李浩然
    2024-08-27

    我修改了类型文件中 `WechatMiniprogram.Page.Constructor` 的和 `Options` 类型的定义. 添加了两个新的可选范型 `BehaviorData` 和 `BehaviorMethods`. 在使用 `Page` 的时候把相应的 behavior 的类型传进去.

    type Options<
      TData extends DataOption,
      TCustom extends CustomOption,
      BehaviorData,
      BehaviorMthods
    > = (TCustom &
      Partial<Data<TData>> &
      Partial<ILifetime> & {
        options?: Component.ComponentOptions
      }) &
      ThisType<Instance<TData & BehaviorData, TCustom & BehaviorMthods>>
    
    
    interface Constructor {
      <TData extends DataOption, TCustom extends CustomOption, BehaviorData = {}, BehaviorMethods = {}>(
        options: Options<TData, TCustom, BehaviorData, BehaviorMethods>
      ): void
    }
    
    Page<TData, TOptions, BehaviorData, BehaviorMethods>({
      behaviors: [behavior],
      ...
    })
      
    


    暂时可以解决这个问题, 希望官方能明确下用法或更新下类型库.


    2024-08-27
    有用
    回复
  • 李浩然
    李浩然
    2024-08-27

    我修改了类型文件中 `WechatMiniprogram.Page.Constructor` 的和 `Options` 类型的定义. 添加了两个新的可选范型 `BehaviorData` 和 `BehaviorMethods`. 在使用 `Page` 的时候把相应的 behavior 的类型传进去.

    type Options<
      TData extends DataOption,
      TCustom extends CustomOption,
      BehaviorData,
      BehaviorMthods
    > = (TCustom &
      Partial<Data<TData>> &
      Partial<ILifetime> & {
        options?: Component.ComponentOptions
      }) &
      ThisType<Instance<TData & BehaviorData, TCustom & BehaviorMthods>>
    
    
    interface Constructor {
      <TData extends DataOption, TCustom extends CustomOption, BehaviorData = {}, BehaviorMethods = {}>(
        options: Options<TData, TCustom, BehaviorData, BehaviorMethods>
      ): void
    }
    
    Page<TData, TOptions, BehaviorData, BehaviorMethods>({
      behaviors: [behavior],
      ...
    })
      
    


    暂时可以解决这个问题, 希望官方能明确下用法或更新下类型库.


    2024-08-27
    有用
    回复
  • 李浩然
    李浩然
    2024-08-27

    我修改了类型文件中 `WechatMiniprogram.Page.Constructor` 的和 `Options` 类型的定义. 添加了两个新的可选范型 `BehaviorData` 和 `BehaviorMethods`. 在使用 `Page` 的时候把相应的 behavior 的类型传进去.

    type Options<
      TData extends DataOption,
      TCustom extends CustomOption,
      BehaviorData,
      BehaviorMthods
    > = (TCustom &
      Partial<Data<TData>> &
      Partial<ILifetime> & {
        options?: Component.ComponentOptions
      }) &
      ThisType<Instance<TData & BehaviorData, TCustom & BehaviorMthods>>
    
    
    interface Constructor {
      <TData extends DataOption, TCustom extends CustomOption, BehaviorData = {}, BehaviorMethods = {}>(
        options: Options<TData, TCustom, BehaviorData, BehaviorMethods>
      ): void
    }
    
    Page<TData, TOptions, BehaviorData, BehaviorMethods>({
      behaviors: [behavior],
      ...
    })
      
    


    暂时可以解决这个问题, 希望官方能明确下用法或更新下类型库.

    2024-08-27
    有用
    回复
  • 李浩然
    李浩然
    2024-08-27

    我修改了类型文件中 `WechatMiniprogram.Page.Constructor` 的和 `Options` 类型的定义. 添加了两个新的可选范型 `BehaviorData` 和 `BehaviorMethods`. 在使用 `Page` 的时候把相应的 behavior 的类型传进去.

    type Options<
      TData extends DataOption,
      TCustom extends CustomOption,
      BehaviorData,
      BehaviorMthods
    > = (TCustom &
      Partial<Data<TData>> &
      Partial<ILifetime> & {
        options?: Component.ComponentOptions
      }) &
      ThisType<Instance<TData & BehaviorData, TCustom & BehaviorMthods>>
    
    
    interface Constructor {
      <TData extends DataOption, TCustom extends CustomOption, BehaviorData = {}, BehaviorMethods = {}>(
        options: Options<TData, TCustom, BehaviorData, BehaviorMethods>
      ): void
    }
    
    Page<TData, TOptions, BehaviorData, BehaviorMethods>({
      behaviors: [behavior],
      ...
    })
      
    


    暂时可以解决这个问题, 希望官方能明确下用法或更新下类型库.

    2024-08-27
    有用
    回复

正在加载...

登录 后发表内容
问题标签