JavaScript Issue
Uncaught (in promise) TypeError: Cannot read properties of null
经常遇到的一个错误,要跟踪一下代码很快可以查到原因。
Uncaught (in promise) TypeError: Cannot read properties of null (reading 'message')
at api.interceptors.response.use.message (axios.ts:39:13)
这个由于Golang后端接口返回的数据为NULL引起的:
func ModuleAddHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var req types.ModuleAddReq
if err := httpx.Parse(r, &req); err != nil {
httpx.ErrorCtx(r.Context(), w, err)
return
}
l := auth.NewModuleAddLogic(r.Context(), svcCtx)
resp, err := l.ModuleAdd(&req)
if err != nil {
httpx.ErrorCtx(r.Context(), w, err)
} else {
httpx.OkJsonCtx(r.Context(), w, resp) // 这里应是httpx.OkJsonCtx(r.Context(), w, bizresponse.Response(resp, err))
}
}
}
TypeScript语法?:
和<>
export function _login(req?: components.TLoginReq) {
return api.post<components.TLoginRes>('/api/auth/login', req);
}
req?: components.TLoginReq
这里代表可选参数。
代表函数参数中的可选参数、接口属性中的可选属性。
可选参数注意几个点
- 在所有必须参数后面的带默认初始化的参数都是可选的
- 可选参数与末尾的默认参数共享参数类型
- 在定义对象接口时也可代表可选属性
(?:)
api:这是一个对象,它包含了用于进行网络请求的方法,其中包括 get 方法,get 方法是一个泛型函数。
通过在尖括号内提供返回类型<TBucketInfoRes>
参数,告诉编译器我们期望的响应数据类型是 TBucketInfoRes
。这样,编译器在解析和类型检查代码时,会相应地将响应数据的类型设置为 TBucketInfoRes
。这样,在发送 GET 请求到 '/api/auth/bucketInfo'
端点后,返回的响应数据会被自动解析成 TBucketInfoRes
类型,并作为 Promise
对象的结果返回。
总结起来,< >
尖括号语法用于指定泛型类型参数,允许我们在使用泛型方法或类时明确指定类型参数的值。在这个场景中,我们使用 <TBucketInfoRes>
来指定 api.get 方法的类型参数,即指定响应数据的类型为 TBucketInfoRes
。
定义接口 TBucketInfoRes 可以提供类型定义和约束、提高代码可读性和维护性、增加代码重用性,并促进与其他开发人员的协作。
PHP7中也有类似的写法:三元运算符 ?:
简写。
调用泛型函数
- TypeScript 泛型函数调用
- 04-简化泛型函数调用_哔哩哔哩_bilibili
- TypeScript(四) —— 函数,接口,类,泛型语法总结 - 知乎
- 【豁然开朗】为什么要用那么复杂的TS - 掘金
- TypeScript-从函数返回类型开始讲怎么用好TS - 知乎
其他参考
- TS使用的初衷
- TypeScript 函数 泛型函数 区别
- ts必备基础知识总结_ts 尖括号_Hdudw的博客-CSDN博客
- 🚀 TS项目如何高效处理接口返回数据 - 掘金
- 泛型 · TypeScript中文网 · TypeScript——JavaScript的超集
- TypeScript 泛型 - TypeScript 教程 - 网道
- 《TypeScript 教程》发布了 - 阮一峰的网络日志
- 写给前端新人的话:为什么要用那么复杂的TS - 知乎
- TypeScript是什么,为什么要使用它? - 知乎
- TS入门篇 | 详解 TypeScript 函数类型 - 掘金
- 你不知道的 TypeScript 泛型(万字长文,建议收藏) - 知乎
- 看懂复杂的TypeScript泛型运算 - 掘金
- Typescript(真的)遵循泛型中参数化类型(T,U,V,W)的命名约定吗?_baoleilei6的博客-CSDN博客
JS中不加分号时报错的情况
//前面不加分号会报错 TypeError: console.log(...) is not a function
(data.data || []).map((item, index) => {
console.log(`Visit ${index}`);
if(item.product_icon){
item.product_icon = `https://${item.product_icon}`
}
return item;
})
原因
在使用已( )和[ ]为开头的语句时, 要尤其注意, 因为这两个操作符会优先和前面的表达式进行组合。 如果没有;号的阻断, 解释器直接把两条语句合并.
JS 两种变量导入方式
CommonJS 的 require 导入方式
ES6 的 import 导入方式
const {
getProjectGroupingList,
addDevicePreFind,
addEquipment,
addProject
} = require("../../../utils/api");
import {
_queryDeviceGroup,
_createDeviceGroup,
_createDevice
} from '../../../utils/newapi'
// newapi.js
let util = require('./newutil')
// 全局配置
export function getConfigOptions(data) {
return util.request('get', '/api/main/configOptions', data)
}
// 登录 - 拿token
export function _login(data) {
return util.request('post', '/api/auth/login', data)
}
两种导入方式在语法上有一些差异,但它们的作用是一样的,即导入其他模块中导出的函数或对象,以便在当前模块中使用。