use*_*909 9 string typescript logical-or
当我做打字稿时:
let token = req.headers['x-access-token'] || req.headers['authorization'] as string;
Run Code Online (Sandbox Code Playgroud)
我有一个错误:
Argument of type 'string | string[]' is not assignable to parameter of type 'string'
Run Code Online (Sandbox Code Playgroud)
任何人都知道什么是 'string | 字符串[]'类型?我的意思是如果我想在打字稿中使用两个字符串的逻辑“或”。怎么做?
以及如何转换 'string | string[]' 类型到字符串类型?
Adr*_*and 11
尝试
let token = (req.headers['x-access-token'] || req.headers['authorization']) as string;
Run Code Online (Sandbox Code Playgroud)
编译器认为 req.headers['some string'] 是一个字符串数组,当您将 or 运算符的一侧强制转换时,您会得到一种字符串或字符串数组。所以对它们执行 or ,然后将结果强制为字符串。
任何人都知道什么是“字符串|” string[]' 类型?我的意思是,如果我想在打字稿中使用两个字符串的逻辑“或”。怎么做?
string | string[]是类型联合(TS Docs),这意味着相对值可以是string OR string[](或Array<string>字符串数组)。
||当且仅当左操作数包含虚假类型(undefined、null、number和string)时,两个变量之间的逻辑或运算符实际上会生成两个变量类型的并集boolean,否则生成第一个变量类型。虚假类型实际上取决于配置(请参阅下面的实际解决方案的注释)。例子:
type NonFalsishType = { prop: number };
let var1: number | undefined = 42;
let var2: string = 'var2'
let var3: NonFalsishType = { prop: 42 };
let test1: number | string = var1 || var2;
let test2: number | string = var2 || var1;
let test3: string | NonFalsishType = var2 || var3;
// strictNullCheck = true
// string type can be omitted because NonFalsishType
// is defenitely not falsy
let test4: NonFalsishType = var3 || var2;
// strictNullCheck = false
// string not omitted because null can be assigned to var3
let test4: NonFalsishType | string/* | null*/ = var3 || var2;
Run Code Online (Sandbox Code Playgroud)
以及如何投射'string | string[]'类型转换为字符串类型?
“强制转换”(正确的名称是类型断言(TS Docs),它是语义上不同的概念)可以通过不同的方式完成,最常见的是通过使用关键字来实现as,但也有尖括号表示法:
// as
let myHeader: string = req.headers['authorization'] as string
// angle brackets
let myHeader: string = <string>req.headers['authorization']
Run Code Online (Sandbox Code Playgroud)
注意:类型断言在运行时根本不执行任何操作,它也不会在 JS 代码中被编译:
// TS
let myHeader: string = req.headers['authorization'] as string
// JS
var myHeader = req.headers['authorization'];
Run Code Online (Sandbox Code Playgroud)
类型断言只是为了指示 TS 类型检查器强制将一种类型限制为另一种类型,仅在编译阶段的类型检查期间进行。这就像对编译器说“我不关心变量实际上是哪种(联合)类型,将其视为as指定类型”
现在最简单的解决方案是断言string变量的类型:
// TS
let myHeader: string = req.headers['authorization'] as string
// JS
var myHeader = req.headers['authorization'];
Run Code Online (Sandbox Code Playgroud)
这个解决方案会导致不同的问题:如果客户端向服务器发送多个x-access-token/authorization标头怎么办?
您最终将在 token 变量中得到一个数组,这意味着您生成的代码可能会中断(例如,token.substr(10)将产生运行时错误,因为数组没有substr属性,而字符串有)。
x-access-token/authorization如果客户端根本不发送标头(undefined属性将中断任何访问器的执行),情况会更糟。
您需要思考您需要实现什么目标。TypeScript 类型符号不仅仅用于装饰代码,实际上还可以通过类型和模式检查生成高质量的代码。您不应该忽视一个变量可以采用多种类型的事实,否则您将在生产环境中遇到错误和安全问题。
如果您的真正目的是验证访问令牌,您应该确保该令牌非空且唯一,以便识别用户:
// parenthesis emphasize where the assertion is applied
let token: string = (req.headers['x-access-token'] as string) ||
(req.headers['authorization'] as string);
let token: string = (
req.headers['x-access-token'] ||
req.headers['authorization']
) as string;
// no runtime differences, just saying to the TS type checker
// two different way to see the same variables
Run Code Online (Sandbox Code Playgroud)
笔记:
req.headers[key]正如@TmTron的答案所述,其类型为string | string[] | undefined,但undefined在错误的联合类型中未提及。这是因为可以配置 TypeScript(在 中tsconfig.json或 通过传递正确的命令行参数)在类型检查期间忽略虚假值(例如false、null和undefined)。该选项是strictNullCheck(TS Docs),默认设置为false(意味着 TS 在类型检查时将忽略假值)。如果您将该选项设置为true错误将变为:
Argument of type 'string | string[] | undefined' is not assignable to parameter of type 'string'
Run Code Online (Sandbox Code Playgroud)
迫使您也考虑这种undefined情况(根据我的经验,这通常可以防止许多非常多的错误)
多个token的情况比较模糊,你应该和你的意图达成一致:
token = token[0] || ''并删除else后续else if(成为if (!token) ...)中的 - 仍然可行,但不是真正干净的解决方案实际上,有一些使用扩展令牌(逗号分隔令牌)的身份验证技术,但在安全实现的日常使用中非常稀缺。
另请注意,理论上客户端不应发送具有相同名称的多个标头,但实际上恶意用户可以使用重复的标头模拟对服务器的调用,以利用应用程序的某些漏洞。这就是为什么您还应该验证数组情况的原因。
我猜你正在使用 node.js。在这种情况下req.headers是IncomingHttpHeaders具有以下索引签名的类型:[header: string]: string | string[] | undefined;
这意味着,req.headers['whatever']可以是类型string或string[](字符串数组)或undefined
req.headers['x-access-token']有类型string | string[] | undefinedreq.headers['authorization'] as string是类型stringtoken是string | string[],因为
string | string[]or将使用类型为的第二部分string提示
而不是req.headers['authorization']您可以使用req.headers.authorizationwhich 类型string | undefined。
interface IncomingHttpHeaders {
..
'authorization'?: string;
..
[header: string]: string | string[] | undefined;
}
Run Code Online (Sandbox Code Playgroud)
详细
说明:Adrian Brand的回答很好,您可以按原样使用。为了完成起见,我将展示如何处理所有情况并解释类型的详细方法:
const tokenValue= req.headers['x-access-token'] || req.headers['authorization'];
Run Code Online (Sandbox Code Playgroud)
tokenValue是 类型string | string[] | undefined。
请注意,它也可以undefined在不存在任何标题时出现。
我们可以处理这种情况:
if (!tokenValue) throw Error('missing header')
Run Code Online (Sandbox Code Playgroud)
在此检查之后,打字稿足够聪明,可以知道tokenValue现在的类型string | string[]
if (Array.isArray(a)) {
throw Error('token must be a string');
// note: you could also extract the first array item and use that as your token.
} else {
// In this if branch, the type of`tokenValue` is `string`
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8202 次 |
| 最近记录: |