类型“字符串或空”不可分配给类型字符串 (TS)

目录

Type ‘string or null’ is not assignable to type string (TS)

  1. 类型“字符串或空”不可分配给类型字符串 (TS)
  2. 参数类型“字符串或空”不能分配给字符串类型的参数
  3. 类型“null”不可分配给 TypeScript 中的类型

类型 ‘string or null’ 不可分配给类型字符串 (TS)

当将可能的null值分配给期望string.

string要解决该错误,请在赋值之前使用非空断言或类型保护来验证值是否为 a 。

下面是错误如何发生的示例。

索引.ts
interface Employee { id: number; name: string | null; } const emp: Employee = { id: 1, name: 'Bobby Hadz', }; // ⛔️ Error: Type 'string | null' is // not assignable to type 'string'. // Type 'null' is not assignable to type 'string'.ts(2322) const name: string = emp.name;

接口name中的属性类型为
.
Employee
string | null

name变量的类型为 a string,因此它只希望获得一个值 a string

TypeScript 告诉我们该emp.name属性的值可能为null,这与变量的类型不兼容,后者只需要一个. namestring

使用非空断言操作符解决错误

解决该错误的一种方法是使用
非空断言 (!) 运算符

索引.ts
interface Employee { id: number; name: string | null; } const emp: Employee = { id: 1, name: 'Bobby Hadz', }; // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const name: string = emp.name!; // 👈️ non-null assertion

感叹号是
TypeScript 中的
非空断言运算符。

在不进行任何显式类型检查的情况下从类型中删除null和。undefined

当你使用这种方法时,你基本上告诉 TypeScript 这个值永远不会是nullor undefined

使用类型断言解决错误

这与
类型断言非常相似
,只有在您绝对确定该值属于预期类型时才应使用。

索引.ts
interface Employee { id: number; name: string | null; } const emp: Employee = { id: 1, name: 'Bobby Hadz', }; const name: string = emp.name as string; // 👈️ type assertion console.log(name); // 👉️ "Bobby Hadz"
当我们有关于 TypeScript 不知道的值类型的信息时,使用类型断言。

我们有效地告诉 TypeScript 这emp.name将是一个字符串,不用担心。

使用类型保护来解决错误

另一种更好的方法是使用
类型保护

索引.ts
interface Employee { id: number; name: string | null; } const emp: Employee = { id: 1, name: 'Bobby Hadz', }; const name: string = emp.name !== null ? emp.name : ''; console.log(name); // 👉️ "Bobby Hadz"

三元运算符与语句非常相似if/else

如果问号左边的表达式为真,则运算符返回冒号左边的值,否则返回冒号右边的值。

如果该属性不等于null,则将其分配给name变量,否则,我们使用空字符串作为后备。

这样我们就可以确保name变量总是会被分配一个字符串,即使emp.namenull

使用 nullish 合并运算符 (??) 来解决错误

您还可以使用
无效合并运算符 (??)
来解决错误。

索引.ts
interface Employee { id: number; name: string | null; } const emp: Employee = { id: 1, name: 'Bobby Hadz', }; const name: string = emp.name ?? ''; console.log(name); // 👉️ "Bobby Hadz"
无效合并运算符 (??) 使我们能够为值是nullor时指定回退undefined

因此,如果emp.namenullor undefined,我们将name变量设置为空字符串。

使用逻辑或(||)运算符解决错误

您也可以

以类似的方式使用
逻辑或 (||)运算符。

索引.ts
interface Employee { id: number; name: string | null; } const emp: Employee = { id: 1, name: 'Bobby Hadz', }; const name: string = emp.name || ''; console.log(name); // 👉️ "Bobby Hadz"

如果左边的值是假的,逻辑 OR (||) 运算符返回右边的值。

这与无效合并运算符 (??) 不同,因为无效合并仅检查nullundefined

如果左侧的值是以下任何值,则逻辑 OR (||) 运算符将返回右侧的值:null, undefined, false, 0, ""(空字符串),NaN(非数字)。

使用if语句解决错误

if即使是作为类型保护的简单语句也可以用来解决错误。

索引.ts
interface Employee { id: number; name: string | null; } const emp: Employee = { id: 1, name: 'Bobby Hadz', }; let name = ''; if (emp.name !== null) { name = emp.name; } console.log(name); // 👉️ "Bobby Hadz"

我们使用let关键字将name变量初始化为空字符串。

if语句中,我们检查emp.name属性是否不等于
null并将name变量分配给相应的值。

出现“Type ‘string | null’ is not assignable to type string”错误的原因是左右两边值的类型不兼容。

如果您收到“对象可能为‘空’”错误,请查看
我的另一篇文章

更新值的类型来解决错误

根据您的用例,您可以通过向左或向右更新值的类型并使它们兼容来解决错误。

索引.ts
interface Employee { id: number; name: string | null; } const emp: Employee = { id: 1, name: 'Bobby Hadz', }; // 👇️ const name: string | null const name: string | null = emp.name; console.log(name); // 👉️ "Bobby Hadz"

我们显式地将变量的类型设置name为,它与接口中属性string | null的类型相同nameEmployee

参数类型 ‘string or null’ 不能分配给字符串类型的参数

当将可能的值传递给null需要string.

string要解决该错误,请在将值传递给函数之前使用类型保护来验证该值是否为 a 。

参数类型 null 不可分配的参数字符串

下面是错误如何发生的示例。

索引.ts
function getMessage(message: string) { return message; } const value = Math.random() > 0.5 ? 'hello' : null; // ⛔️ Error: Argument of type 'string | null' is not // assignable to parameter of type 'string'. // Type 'null' is not assignable to type 'string'.ts(2345) getMessage(value);

该函数期望使用 type 的参数调用,string但提供的参数可能是null.

TypeScript 告诉我们传递给函数的值可能是null,这与函数参数的类型不兼容,即string.

使用非空断言解决错误

解决这个问题的一种方法是使用非空断言。

索引.ts
function getMessage(message: string) { return message; } const value = Math.random() > 0.5 ? 'hello' : null; getMessage(value!); // 👈️ non-null assertion

感叹号是
TypeScript 中的
非空断言运算符。

在不进行任何显式类型检查的情况下从类型中删除null和。undefined

当你使用这种方法时,你基本上告诉 TypeScript 这个值永远不会是nullor undefined

使用类型断言解决错误

这与
类型断言非常相似
,只有在您绝对确定该值属于预期类型时才应使用。

索引.ts
function getMessage(message: string) { return message; } const value = Math.random() > 0.5 ? 'hello' : null; getMessage(value as string); // 👈️ type assertion
当我们有关于 TypeScript 不知道的值类型的信息时,使用类型断言。

我们有效地告诉 TypeScript 变量存储了一个字符串,不用担心。

使用类型保护来解决错误

另一种更好的方法是使用
类型保护

索引.ts
function getMessage(message: string) { return message; } const maybeString = Math.random() > 0.5 ? 'hello' : null; const message: string = maybeString !== null ? maybeString : ''; getMessage(message);

我们使用
三元运算符来检查maybeString变量是否不等于null

如果它不等于null,它被分配给message变量,否则,我们使用一个空字符串作为后备。

这样我们就可以确保message变量总是会被分配一个字符串,即使maybeString变量是. null

使用 nullish coalescing (??) 运算符解决错误

您还可以使用
无效合并运算符 (??)
来解决错误。

索引.ts
function getMessage(message: string) { return message; } const maybeString = Math.random() > 0.5 ? 'hello' : null; getMessage(maybeString ?? '');
无效合并运算符 (??) 使我们能够为值是nullor时指定回退undefined

因此,如果maybeString变量是nullor undefined,我们将一个空字符串参数传递给函数。

使用逻辑或(||)运算符解决错误

您也可以

以类似的方式使用
逻辑或 (||)运算符。

索引.ts
function getMessage(message: string) { return message; } const maybeString = Math.random() > 0.5 ? 'hello' : null; getMessage(maybeString || '');

如果左边的值是假的,逻辑 OR (||) 运算符返回右边的值。

这与无效合并运算符 (??) 不同,因为无效合并仅检查nullundefined

如果左侧的值是以下任何值,则逻辑 OR (||) 运算符将返回右侧的值:null, undefined, false, 0, ""(空字符串),NaN(非数字)。

更新函数参数的类型来解决错误

出现“Argument of type ‘string | null’ is not assignable to parameter of type string”错误的原因是函数的参数类型与传入参数的类型不
兼容

根据您的用例,您还可以通过更新函数参数的类型并使参数和传入参数的类型兼容来解决错误。

索引.ts
// 👇️ parameter is type string or null function getMessage(message: string | null) { return message; } // 👇️ argument is also type string or null const maybeString = Math.random() > 0.5 ? 'hello' : null; getMessage(maybeString);

该函数的参数现在类型为stringor null,因此我们可以向它传递类型为stringor的参数null,因为这两种类型是兼容的。

想了解更多有关TypeScript 中的键入函数的信息吗? 查看这些资源: 如何在 TypeScript 中设置默认参数在 TS 中的函数或类中设置可选参数如何在 TypeScript 中键入异步函数

Type ‘null’ 不可分配给 TypeScript 中的类型

使用联合类型解决 TypeScript 中的“Type ‘null’ is not assignable to type”错误,例如name: string | null.

值的类型必须接受,null因为如果它不接受并且您已
tsconfig.json
strictNullChecks中启用
,则类型检查器会抛出错误。

下面是错误如何发生的示例。

索引.ts
// 👇️ Function return value set to object function getObj(): Record<string, string> { if (Math.random() > 0.5) { // ⛔️ Error Type 'null' is not assignable to type // 'Record<string, string>'.ts(2322) return null; } return { name: 'Bobby Hadz' }; }

这是另一个例子。

索引.ts
interface Person { name: string; // 👈️ name property set to string } const obj: Person = { name: 'Bobby Hadz' }; // ⛔️ Type 'null' is not assignable to type 'string'.ts(2322) obj.name = null;

第一个示例中的函数返回一个null值或一个对象,但我们没有指定该函数可能返回null

string第二个示例中的对象的属性类型为name,但我们试图将null导致错误的属性设置为。

使用联合类型解决错误

您可以使用联合类型来解决错误。

索引.ts
// 👇️ using union function getObj(): Record<string, string> | null { if (Math.random() > 0.5) { return null; } return { name: 'Bobby Hadz' }; }

这里是如何使用联合来解决接口示例。

索引.ts
interface Person { // 👇 using union name: string | null; } const obj: Person = { name: 'Bobby Hadz' }; obj.name = null;

我们使用联合类型将函数的返回值设置为具有字符串键和值的对象或null.

null这种方法允许我们从函数返回一个对象或一个值。

在第二个示例中,我们将对象中的属性设置为orname类型stringnull

现在我们可以将属性的值设置为 ,null而不会出现错误。

使用类型保护来检查属性是否不存在null

如果您必须访问该name属性,例如调用toLowerCase()
其上的方法,则必须使用类型保护,因为该属性可能是
null.

索引.ts
interface Person { // 👇 using union name: string | null; } const obj: Person = { name: 'Bobby Hadz' }; // ⛔️ Error: 'obj.name' is possibly 'null' obj.name.toLowerCase();

您可以使用简单的类型保护来解决这个问题

索引.ts
interface Person { // 👇 using union name: string | null; } const obj: Person = { name: 'Bobby Hadz' }; if (obj.name !== null) { // ✅ Now obj.name is string console.log(obj.name.toLowerCase()); }

strictNullChecks通过设置来抑制错误false

可以通过在文件中
设置
strictNullChecks为来抑制错误falsetsconfig.json

tsconfig.json文件
{ "compilerOptions": { "strictNullChecks": false, // ... 👇️ rest } }

strictNullChecks设置为false,null并且undefined被语言忽略。

这是不可取的,因为它会在运行时导致意外错误。

当您设置strictNullCheckstrue,nullundefined拥有自己的类型时,当需要不同类型的值时使用它们时会出现错误。

额外资源

您可以通过查看以下教程来了解有关相关主题的更多信息: