Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于types感应 #21

Closed
roytan883 opened this issue May 15, 2020 · 6 comments
Closed

关于types感应 #21

roytan883 opened this issue May 15, 2020 · 6 comments

Comments

@roytan883
Copy link

我参考例子
https://codesandbox.io/s/concent-guide-xvcej?file=/src/types/store.d.ts

在放数据模型的文件夹写了一个concent.d.ts

import {StateType, ReducerType, ComputedValType, cst, MODULE_VOID, ICtx, IAnyFn} from 'concent';

import appState from "./state";
import * as appReducer from './reducer';
import * as appComputed from './computed';

export type AppState = StateType<typeof appState>;
export type AppReducer = ReducerType<typeof appReducer>;
export type AppComputed = ComputedValType<typeof appComputed>;

export type RootState = {
    [cst.MODULE_GLOBAL]: {},
    [cst.MODULE_DEFAULT]: {},
    [cst.MODULE_VOID]: {},
    app: AppState,
}

export type RootRd = {
    app: AppReducer,
}

export type RootCu = {
    app: AppComputed,
}

export type ICtxM<P, S, M, Se = {}> = S extends IAnyFn ?
    ICtx<RootState, RootRd, RootCu, P, ReturnType<S>, M, MODULE_VOID, Se> :
    ICtx<RootState, RootRd, RootCu, P, S, M, MODULE_VOID, Se>;

reducer.js有一个函数

export function makeNewFirstName({name}, state, ctx) {
  console.log(`reducer-23 name: `, name)
  console.log(`reducer-23 state: `, state)
  console.log(`reducer-23 ctx: `, ctx)
  return {firstName: name}
}

但是我在fn控件上使用的时候

appCtx.moduleReducer.makeNewFirstName({name: 'AAA-' + Date.now()})

虽然调用成功,但是webstorm还是提示makeNewFirstName函数不识别,没法点函数自己跳过去。

请问这是有哪里没弄对吗?

@roytan883
Copy link
Author

必须命名成store.d.ts?

@fantasticsoul
Copy link
Contributor

fantasticsoul commented May 16, 2020

不是的,和名字没关系,你应该没有为appCtx标注正确的类型,store.d.ts只是一个集中维护类型的地方(也就是你的concent.d.ts),组件需要根据自己所标记属于的模块或者连击的模块使用ICtx_xxx组装正确的类型赋值给你的appCtx

注意看这个示例
https://codesandbox.io/s/concent-guide-xvcej?file=/src/pages/FnVsClass/BetterFnDemo.js

/**
 * 这里在使用ICtxM给实例上线推导出正确的类型
 * @typedef {import('types/store').ICtxM<{renderBy:string}, {}, 'bar'>} CtxPre
 */

// 这里在给ctx赋值类型CtxPre
export const setup = (/**@type {CtxPre}*/ ctx) => {
  console.log(
    "setup will only been executed one time before first rendering period!"
  );
}

然后你就能调用所属模块的方法了
image

如果是ts工程,可参照这里链接里的示例
https://codesandbox.io/s/concent-guide-ts-zrxd5?file=/src/pages/MultiConn/index.tsx:827-842

结论

你没有给实例上下文标记正确的类型导致的IDE无法识别和调整

@roytan883
Copy link
Author

@fantasticsoul

麻烦帮我看看哪里的问题

package.json

"devDependencies": {
"typescript": "3.9.2",

jsconfig.json

{
  "compilerOptions": {
    "experimentalDecorators":true
  },
  "exclude": [
    "node_modules"
  ]
}

src/tmp-mobile/stores/concent/concent.d.ts

import {StateType, ReducerType, ComputedValType , cst, MODULE_VOID, ICtx } from 'concent';

import appState from "./state";
import * as appReducer from './reducer';
import * as appComputed from './computed';

export type AppState = StateType<typeof appState>;
export type AppReducer = ReducerType<typeof appReducer>;
export type AppComputed = ComputedValType<typeof appComputed>;

export type RootState = {
    [cst.MODULE_GLOBAL]: {},
    [cst.MODULE_DEFAULT]: {},
    [cst.MODULE_VOID]: {},
    app: AppState,
}

export type RootRd = {
    app: AppReducer,
}

export type RootCu = {
    app: AppComputed,
}

export type Modules = keyof RootState;

// ********************************
// 一些常用的基于Ctx封装的辅助类型
// ********************************

/** 属于某个模块 CtxM<P, M, Se, RefCu> */
export type CtxM<P = {}, M extends Modules = MODULE_DEFAULT, Se = {}, RefCu = {}>
    = ICtx<RootState, RootRd, RootCu, P, {}, M, MODULE_VOID, Se, RefCu>;

/** 属于某个模块,扩展了私有状态时 CtxMS<P, M, St, Se, RefCu>*/
export type CtxMS<P = {}, M extends Modules = MODULE_DEFAULT, St = {}, Se = {}, RefCu = {}>
    = ICtx<RootState, RootRd, RootCu, P, St, M, MODULE_VOID, Se, RefCu>;

/** 属于某个模块,连接了其他模块 CtxMConn<P, M, Conn, Se, RefCu> */
export type CtxMConn<P = {}, M extends Modules = MODULE_DEFAULT, Conn extends Modules = MODULE_VOID, Se = {}, RefCu = {}>
    = ICtx<RootState, RootRd, RootCu, P, {}, M, Conn, Se, RefCu>;

/** 属于某个模块,扩展了私有状态,连接了其他模块 CtxMSConn<P, M, St, Conn, Se, RefCu>  */
export type CtxMSConn<P = {}, M extends Modules = MODULE_DEFAULT, St = {}, Conn extends Modules = MODULE_VOID, Se = {}, RefCu = {}>
    = ICtx<RootState, RootRd, RootCu, P, St, M, Conn, Se, RefCu>;

/** 扩展了私有状态,连接了其他模块 CtxMSConn<P, St, Conn, Se, RefCu>  */
export type CtxSConn<P = {}, St = {}, Conn extends Modules = MODULE_VOID, Se = {}, RefCu = {}>
    = ICtx<RootState, RootRd, RootCu, P, St, MODULE_DEFAULT, Conn, Se, RefCu>;

/** 连接了其他模块 CtxConn<P, Conn, Se, RefCu> */
export type CtxConn<P = {}, Conn extends Modules = MODULE_VOID, Se = {}, RefCu = {}>
    = ICtx<RootState, RootRd, RootCu, P, {}, MODULE_DEFAULT, Conn, Se, RefCu>;

// default系列,没有指定连接模块的组件默认属于$$default模块
export type CtxDe<P = {}, Se = {}, RefCu = {}>
    = CtxM<P, MODULE_DEFAULT, Se, RefCu>;
export type CtxDeS<P = {}, St = {}, Se = {}, RefCu = {}>
    = CtxMS<P, MODULE_DEFAULT, St, Se, RefCu>;
export type CtxDeSConn<P = {}, St = {}, Conn extends Modules = MODULE_VOID, Se = {}, RefCu = {}>
    = CtxMSConn<P, MODULE_DEFAULT, St, Conn, Se, RefCu>;
export type CtxDeConn<P = {}, Conn extends Modules = MODULE_VOID, Se = {}, RefCu = {}>
    = CtxSConn<P, MODULE_DEFAULT, Conn, Se, RefCu>;

export type ItemsType<Arr> = Arr extends ReadonlyArray<infer E> ? E : never;

使用src/tmp-mobile/pages/PageConcentTest.js

const PageConcentTest = () => {
  /**@type {import('src/tmp-mobile/stores/concent/concent').CtxM<{renderBy:string}, 'app'>} */
  const appCtx = useConcent("app")

还是没法感应出来

@roytan883
Copy link
Author

加上"baseUrl": ".",在vs code可以感应了,但是webstorm还是不行

@roytan883
Copy link
Author

搞不懂webstorm得这样用才行

/** @typedef {import('src/tmp-mobile/stores/concent/concent').ICtxM<{renderBy:string}, {}, 'app'>} CtxApp */

/**@type CtxApp*/
  const appCtx = useConcent("app")

直接用这个不行

 /**@type {import('src/tmp-mobile/stores/concent/concent').CtxM<{renderBy:string}, 'app'>} */

@fantasticsoul
Copy link
Contributor

额,很久没用webstorm了,和vsc有细节的区别吧……

感觉你的项目目录好深啊, baseurl现在推荐src, 然后目录越浅记忆负担越小,例如像我的示例一样,引入只需要 import('types/store.d.ts')就完事了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants