【问题标题】:How to solve error "Type 'string' is not assignable to type 'number'" in Angular 14?如何解决错误 \"Type \'string\' is not assignable to type \'number\'\" in Angular 14?
【发布时间】:2022-09-22 18:17:39
【问题描述】:

我最近开始学习使用 Angular 14,但是我遇到了一个问题。我想使用在组件中创建的属性“total”,但收到错误“类型'字符串'不可分配给类型'数字'”。

app.component.html 代码是:

<div>
  <app-header></app-header>
  <app-total mensaje="Total por pagar: " total="5000"></app-total>
  <app-items></app-items>
</div>

虽然具有“total”属性的组件,total.component.ts 是:

import { Component, Input, OnInit } from '@angular/core';

@Component({
  selector: 'app-total',
  templateUrl: './total.component.html',
  styleUrls: ['./total.component.css']
})
export class TotalComponent implements OnInit {

  @Input() total:number = 0;
  @Input() mensaje:string = '';

  constructor() { }

  ngOnInit(): void {
  }
}

【问题讨论】:

  • [total]="5000"
  • 诡异的。我第一次尝试时,得到一个错误“类型'未定义'不可分配给类型'数字'”,但现在它突然起作用了。谢谢
  • 据我所知,这是将文字数字或布尔值传递给@Input() 属性的惯用方式。不幸的是,关于绑定的 Angular 文档并没有说得很清楚,所以我将其添加为答案。

标签: angular typescript angular14


【解决方案1】:

您需要使用 property binding 语法将值评估为数字:

<app-total mensaje="Total por pagar: " [total]="5000"></app-total>

【讨论】:

    【解决方案2】:

    <div>
      <app-header></app-header>
      <app-total mensaje="Total por pagar: "  [total]="5000"></app-total>
      <app-items></app-items>
    </div>

    【讨论】:

      【解决方案3】:

      要将数字直接作为数字@Input 传递给组件,或者将true/false 作为布尔值@Input,甚至是数组,而不使用Angular 的Property binding,我们可以利用函数和Angular's CDK Coercion 的类型(如果我们不想依赖 @angular/cdk,也可以创建我们自己的类型)。

      例如,要将数字@Input 传递给组件,我们可以执行以下操作:

      import { coerceNumberProperty, NumberInput } from '@angular/cdk/coercion';
      
      @Input()
      get total() { return this._total; }
      set total(value: NumberInput) {
        // `coerceNumberProperty` turns any value coming in from the view into a number, allowing the
        // consumer to use a shorthand string while storing the parsed number in memory. E.g. the consumer can write:
        // `<app-total total="500"></app-total>` instead of `<app-total [total]="500"></app-total>`.
        // The second parameter specifies a fallback value to be used if the value can't be parsed to a number.
        this._total = coerceNumberProperty(value, 0);
      }
      private _total = 0;
      

      这允许消费者在将解析后的数字存储在内存中时使用速记字符串,如下所示:

      <app-total mensaje="Total por pagar: " total="5000"></app-total>
      

      如果我们不想使用 CDK 的内置函数和类型,我们可以在 components/src/cdk/coercion 文件夹下的 Angular Components repo 中查看它们的定义。

      例如,我们必须定义以下类型和函数来处理number property

      /**
       * Type describing the allowed values for a number input
       */
      export type NumberInput = string | number | null | undefined;
      
      /** Coerces a data-bound value (typically a string) to a number. */
      export function coerceNumberProperty(value: any): number;
      export function coerceNumberProperty<D>(value: any, fallback: D): number | D;
      export function coerceNumberProperty(value: any, fallbackValue = 0) {
        return _isNumberValue(value) ? Number(value) : fallbackValue;
      }
      
      /**
       * Whether the provided value is considered a number.
       */
      export function _isNumberValue(value: any): boolean {
        // parseFloat(value) handles most of the cases we're interested in (it treats null, empty string,
        // and other non-number values as NaN, where Number just uses 0) but it considers the string
        // '123hello' to be a valid number. Therefore we also check if Number(value) is NaN.
        return !isNaN(parseFloat(value as any)) && !isNaN(Number(value));
      }
      

      boolean-propertystring-arrayarray 的功能和类型也是如此。

      【讨论】:

        猜你喜欢
        • 2022-12-02
        • 2022-01-26
        • 2022-11-20
        • 1970-01-01
        • 2022-12-07
        • 1970-01-01
        • 2023-02-25
        • 2022-12-27
        • 2022-12-27
        相关资源
        最近更新 更多