类型 'File | null' 不可分配给类型 'File'。在 angular 11

Type 'File | null' is not assignable to type 'File'. in angular 11

你好我是 Angular 的新手,目前我正在处理 Angular 11 项目,我必须上传一个 CSV 文件并在客户端提取文件记录并保存通过 ASP.NET Web API.

在数据库中

这里我按照教程尝试获取angular端CSV文件的数据,并在同一页面显示。

然后我得到这个错误,

类型 'File | null' 不能分配给类型 'File'。 类型 'null' 不可分配给类型 'File'.ts(2322)

我试了很多方法还是没能解决这个问题。你能帮帮我吗?

这是我的.ts文件,

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

@Component({
  selector: 'app-file-upload',
  templateUrl: './file-upload.component.html',
  styles: [
  ]
})
export class FileUploadComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

  lines: any = [];
  linesR: any = [];

  changeListener(files: FileList) {
    console.log(files);
    if (files && files.length > 0) {
      let file: File = files.item(0);
      console.log(file.name);
      console.log(file.size);
      console.log(file.type);

      let reader: FileReader = new FileReader();
      reader.readAsText(file);
      reader.onload = (e) => {
        let csv: any = reader.result;
        let allTextLines = [];
        allTextLines = csv.split(/\r|\n|\r/);

        let headers = allTextLines[0].split(';');
        let data = headers;
        let tarr = [];
        for (let j = 0; j < headers.length; j++) {
          tarr.push(data[j]);
        }
        this.lines.push(tarr);
        let tarrR = [];
        let arrl = allTextLines.length;
        let rows = [];
        for (let i = 1; i < arrl; i++) {
          rows.push(allTextLines[i].split(';'));
        }
        for (let j = 0; j < arrl; j++) {
          tarrR.push(rows[j]);
        }
        this.linesR.push(tarrR);
      }
    }
  }
}

这是我的.html文件

    <div class="container">
    <h1 style="text-align: center"> File Upload </h1>
    <br><br>

    <input class="form-control" type="file" class="upload" (change)="changeListener($event.target.files)">

    <table class="table table-bordered table-dark">
        <thead>
            <tr>
                <th *ngFor="let item of lines[0]; let i = index">
                    {{item}}
                </th>
            </tr>
        </thead>
        <tbody>
            <tr *ngFor="let item of linesR[0]; let i = index">
                <td *ngFor="let itemm of lines[0]; let j = index">
                    {{item[j]}}
                </td>
            </tr>
        </tbody>
    </table>
</div>

This is the error I got

谢谢!

尝试使用:

fileupload.component.ts

import { Component, OnInit, VERSION } from "@angular/core";
    
@Component({
  selector: 'app-file-upload',
  templateUrl: './file-upload.component.html',
  styles: []
})
export class FileUploadComponent implements OnInit {
      name = "Angular " + VERSION.major;
    
      lines: any = [];
      linesR: any = [];
    
      ngOnInit() {}
    
      changeListener(files) {
        let fileList = (<HTMLInputElement>files.target).files;
        if (fileList && fileList.length > 0) {
          let file: File = fileList[0];
          console.log(file.name);
          console.log(file.size);
          console.log(file.type);
    
          let reader: FileReader = new FileReader();
          reader.readAsText(file);
          reader.onload = e => {
            let csv: any = reader.result;
            let allTextLines = [];
            allTextLines = csv.split(/\r|\n|\r/);
    
            let headers = allTextLines[0].split(";");
            let data = headers;
            let tarr = [];
            for (let j = 0; j < headers.length; j++) {
              tarr.push(data[j]);
            }
            this.lines.push(tarr);
            let tarrR = [];
            let arrl = allTextLines.length;
            let rows = [];
            for (let i = 1; i < arrl; i++) {
              rows.push(allTextLines[i].split(";"));
            }
            for (let j = 0; j < arrl; j++) {
              tarrR.push(rows[j]);
            }
            this.linesR.push(tarrR);
          };
        }
      }
    }

fileupload.component.html

<div class="container">
  <h1 style="text-align: center">File Upload</h1>
  <br /><br />

  <input
    class="form-control"
    type="file"
    class="upload"
    (change)="changeListener($event)"
  />

  <table class="table table-bordered table-dark">
    <thead>
      <tr>
        <th *ngFor="let item of lines[0]; let i = index">
          {{item}}
        </th>
      </tr>
    </thead>
    <tbody>
      <tr *ngFor="let item of linesR[0]; let i = index">
        <td *ngFor="let itemm of lines[0]; let j = index">
          {{item[j]}}
        </td>
      </tr>
    </tbody>
  </table>
</div>

您正在使用 strict: true 打字稿。那挺好的!你面临的问题是这篇文章:

let file: File = files.item(0);

可以 return 未定义,即使您之前检查过长度。这将使类型 File | null ,但您声明它应该只是 File.

最好将其更改为以下内容:

changeListener(files: FileList) {
 const file: File | null = files?.item(0);

 if (file) {
   // here `file` will have type `File` because it has been asserted with the `if`
      console.log(file.size);
      console.log(file.type);

      let reader: FileReader = new FileReader();
      reader.readAsText(file);
      reader.onload = (e) => {
  //...
 

如果您确定您会将值写入文件项,那么您可以说:

let file: File = files.item(0) as File;

我对此没有问题:

const file = files.item(0);
if (file && file !== null) {
  ...

还有这个:

const file: any = files.item(0);
if (file && file !== null) {
  ...

即使我使用 files[0] 而不是 files.item(0)。而这一切都在 strict 模式下。

另一种解决方案是 -

let file: File | any = null;

let file: File | null = null;

如果你想使文件为空,请执行此操作 file= new File([],''); 它将文件对象重新初始化为空文件对象