【问题标题】:Typescript Declaration Merging not working across projects打字稿声明合并不能跨项目工作
【发布时间】:2021-10-12 01:31:43
【问题描述】:

我的主要目标是能够在我的应用程序的前端和后端使用类型。 我已经阅读了有关参考资料并将它们添加到我的 tsconfig.json 中。问题是我对快速响应对象所做的合并声明未被前端识别并返回为any

示例: 我有一个dashboard.ts(控制器),它现在只有一个函数来返回仪表板数据。

dashboard.ts

import * as userModel from '../entities/user';
import * as modelModel from '../entities/model';

export const getData = async (req: Express.Request, res: Express.Response) => {
    const model = await modelModel.getActive();
    const availableStaff = await userModel.count();

    return res._json(200, {
        model,
        availableStaff,
    });
};

export type GetDataReturnType = Unpacked<ReturnType<typeof getData>>;
/**
 * Gives me 
 * 
 * type GetDataReturnType = {
    model: Model & {
        committees: (Committee & {
            delegations: Delegation[];
            directors: User[];
        })[];
        registrations: Registration[];
    };
    availableStaff: number;
}
 */

然后我导出类型GetDataReturnType,这样前端也可以使用它。

注意事项:

  • 我创建了一个 Unpacked 类型来获取没有 Promise&lt;&gt; 的 ReturnType
  • _json 是我创建的合并到 Express.Response 对象的声明(代码如下)

server/src/@types/express/index.d.ts

declare global {
    namespace Express {
        interface Response {
            _json: <T>(status: number, body: T) => T;
        }
    }
}

export {};

res._json 实现在 server/src/server.ts

app.response._json = (status, body) => {
    app.response.status(status).json(body);

    return body;
};

在后端,一切正常。

但是,当我在客户端中导入GetDataReturnType 时,类型为any

/web/src/hooks/useDashboard.ts

import { useQuery } from 'react-query';
import { api } from '../services/api';

import type { GetDataReturnType } from '@controller/dashboard'; 
/**
 * Gives me
 * 
 * type GetDataReturnType = any
 */

import * as DateFns from 'date-fns';

const fetchDashboard: QueryFn<GetDataReturnType> = async () => {
    const response = await api.get<GetDataReturnType>('/dashboard');

    return response.data;
};

export const useDashboard = () => {
    const { data: dashboard, status } = useQuery(
        ['dashboard'],
        fetchDashboard,
        {
            staleTime: DateFns.hoursToMilliseconds(5),
        }
    );

    return { dashboard, status };
};

这是我的server/tsconfig.json

{
    "compilerOptions": {
        "target": "es6" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */,
        "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
        "moduleResolution": "node",
        "sourceMap": false /* Generates corresponding '.map' file. */,
        "outDir": "../build" /* Redirect output structure to the directory. */,
        "removeComments": true /* Do not emit comments to output. */,

        /* Strict Type-Checking Options */
        "strict": true /* Enable all strict type-checking options. */,
        "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
        "strictNullChecks": true /* Enable strict null checks. */,
        "strictFunctionTypes": true /* Enable strict checking of function types. */,
        "strictBindCallApply": true /* Enable strict 'bind', 'call', and 'apply' methods on functions. */,
        "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */,
        "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */,
        "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */,

        "baseUrl": "./" /* Base directory to resolve non-absolute module names. */,
        "paths": {
            "@schemas/*": ["./src/schemas/*"],
            "@server/*": ["./src/*"]
        } /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */,
        "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,

        "skipLibCheck": true /* Skip type checking of declaration files. */,
        "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */,
        "composite": true
    },
    "include": ["src", "src/@types/index.d.ts", "src/@types/express/index.d.ts"]
}

这是我的web/tsconfig.json

{
    "compilerOptions": {
        "target": "es5",
        "lib": ["dom", "dom.iterable", "esnext"],
        "allowJs": true,
        "skipLibCheck": true,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "forceConsistentCasingInFileNames": true,
        "noFallthroughCasesInSwitch": true,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "noEmit": true,
        "jsx": "react-jsx",
        "isolatedModules": true,
        "sourceMap": false,
        "strict": true,
        "noImplicitAny": true,
        "strictNullChecks": true,
        "strictFunctionTypes": true,
        "strictPropertyInitialization": true,
        "noImplicitThis": true,
        "rootDir": "./src",
        "paths": { "@controller/*": ["../server/src/controller/*"] }
    },
    "references": [{ "path": "../server" }],
    "include": ["src"]
}
  • serverweb 在同一个目录中

【问题讨论】:

    标签: node.js typescript typescript-typings


    【解决方案1】:

    查看这个问题,我意识到我忘记在web/tsconfig.jsoninclude 选项中添加"../server/src/@types/**/*"。现在,它完美运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-03
      • 1970-01-01
      • 2021-12-21
      相关资源
      最近更新 更多