是 否 有 玫 瑰 悄 然 绽 放

onedrive-vercel-index在vercel中自定义环境变量报错

2023.08.25

类型断言不是类型转换,更像是类型的选择

0x00 先上结论

直接修改配置文件config/api.config.js

module.exports = {
    
  clientId: process.env.CLIENT_ID  || '',
  obfuscatedClientSecret: process.env.SECRET_KEY  || '',
    
}

之所以报错Type ‘string | string[]‘ is not assignable to type ‘string | undefined‘

是因为typescript开启了空值检查 并且这里不能类比python直接使用类型转换 而是使用断言 告诉编译器 我将类型选择成什么….

0x01 事情起因

偶然发现一个onedrive-index的项目ui很好看支持在线预览视频、音频、图片, 而且使用vercel部署,但是做到最后一步 发现竟然把azure的应用的id和key硬编码在github里….这让我很难受…

查了下讨论区 可以自定义环境变量 但是一直报错

image-20230826174538950

评论区下面有人说加了! 可以

0x02 过程

于是顺着线索 ! 查是感叹号是 typescript中的非空断言符

我尝试下面这样的操作发现js不支持 !

module.exports = {
  clientId: process.env.client_Id !,
  obfuscatedClientSecret: process.env.Secret_Key !,
}

走读代码后 在src/pages/api/index.ts

const clientSecret = revealObfuscatedToken(apiConfig.obfuscatedClientSecret!)

依旧报上面的错误

又尝试干脆直接在这里取值 不走js配置文件

const clientSecret = revealObfuscatedToken(process.env.Secret_Key!)

编译通过了,但是这种方法需要改动的位置有四处 本着求知的欲望 有了下面的探索

0x03 原理

TypeScript 2.0 增加了对不可为空类型的支持。有一种新的严格空值检查模式,他提供了 strictNullChecks

非空断言操作符(!)仅在启用’strictNullchecks’标志的时候才生效。当关闭该标志时,编译器不会检查undefined类型 null类型的赋值

注意点 1

在严格空值检查模式下,null 和 undefined 无法赋值给其他类型的变量

例如下面的代码在 *strictNullChecks=true 下,是无法编译通过的。

let userName: string;
userName = "搞前端的半夏";  // OK
userName = null;      // OK
userName = undefined; // OK

注意点 2

严格空值检查并不意味着变量的类型无法设置为 null 和 undefined

例如下面的代码在 *strictNullChecks=true 下,正常编译通过的。

let userName: null;
userName = null;  

let age: undefined;
age = undefined;  

Typescript 2.3 引入了一个新的 --strict 编译选项,它会开启一些相关的其他编译选项来使用更严格的类型检查。

到 2021 年 8 月 Typescript 4.3 为止,--strict 选项会启用下面的八个编译选项:

  • –alwaysStrict
  • –strictBindCallApply
  • –strictFunctionTypes
  • –strictNullChecks
  • –strictPropertyInitialization
  • –noImplicitAny
  • –noImplicitThis
  • –useUnknownInCatchVariables

通过查看配置文件 tsconfig.json 发现 "strict": true

0x04 解决方法

  • 在tsconfig.json中添加 strictNullChecks=false 关闭检查

  • 在四个位置添加! (上文提到)

  • 联合类型

     clientId: process.env.CLIENT_ID  || '',     //这里必须传入一个字符串可以为空
     obfuscatedClientSecret: process.env.SECRET_KEY  || '',
    
  • 类型保护(未探索)

这里当然推荐方法3 相对于1 改动地方少 , 相对于2 不必为了这一个地方而关闭对整个代码的检查

参考链接:

onedrive-vercel-index 官方文档

typescript 中类型断言理解

Typescript 中的 –strict 编译选项 ——TypeScript Evolution 系列第二十二篇

TypeScript 配置严格 null 类型检查 strictNullChecks

【稳妥的TypeScript】联合类型、交叉类型和类型保护

发表评论