升级Angular版本后CryptoJS.SHA256报类型不匹配错误如何解决
Angular版本升级时,通常会同步升级TypeScript版本、项目依赖的@types/crypto-js类型定义包,新版本的类型校验规则更严格。CryptoJS.SHA256方法的第一个入参仅支持两种类型:string(普通字符串)、CryptoJS.lib.WordArray(CryptoJS内部的字数组对象,要求包含words/sigBytes/concat等属性和方法)。
你的代码中自定义hash方法的入参key被定义为{ toString: () => any }类型,这个类型既不符合string类型要求,也没有实现WordArray类型要求的所有属性,因此触发类型校验报错。旧版本类型定义校验宽松,所以代码可以正常运行。
另外原代码还存在变量复用的类型混乱问题:将CryptoJS.SHA256返回的WordArray类型结果重新赋值给原本存输入参数的key变量,也会加剧类型冲突。
方案1(推荐):传参前显式转字符串,修正变量语义
你的入参key本身就定义了toString方法,本来就是要将其转成字符串后做哈希,直接在传参时显式调用toString,同时不要复用key变量存哈希结果,从根源消除类型不匹配:
hash: function hash(key: { toString: () => string }): string { // 显式转字符串匹配入参要求,单独定义变量存哈希结果 const hashResult = CryptoJS.SHA256(key.toString(), SECRET_KEY); return hashResult.toString(); }
方案2:直接修正入参类型定义
如果调用hash方法时传入的key本身就只能是字符串或者CryptoJS的WordArray对象,直接把入参类型改成和CryptoJS要求的一致即可:
// 先确保已安装类型依赖:npm i @types/crypto-js -D hash: function hash(key: string | CryptoJS.lib.WordArray): string { const hashResult = CryptoJS.SHA256(key, SECRET_KEY); return hashResult.toString(); }
方案3(临时兜底):类型断言绕过校验
如果暂时不想调整原有逻辑,可以通过类型断言强制告诉TS该参数符合类型要求,但这种方式会绕过TS类型校验,可能隐藏潜在的类型问题,不推荐长期使用:
hash: function hash(key: { toString: () => any }): any { key = CryptoJS.SHA256( key as unknown as string | CryptoJS.lib.WordArray, SECRET_KEY ); return key.toString(); }
注意:如果项目未安装crypto-js对应的TypeScript类型定义包,需要先执行
npm i @types/crypto-js -D安装开发依赖,否则TS无法识别CryptoJS.lib.WordArray类型会触发新的报错。
内容的提问来源于stack exchange,提问作者Nishit bhardwaj

