【发布时间】: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<>的 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"]
}
-
server和web在同一个目录中
【问题讨论】:
标签: node.js typescript typescript-typings