Tìm kiếm trang web

javascript - Tại sao `return` ngầm định của hàm mũi tên không hoạt động trong trường hợp này (TS)?


Cập nhật:

Tại thời điểm này, tôi không còn có thể tái hiện nó trên máy cục bộ, sau khi tôi chạy

rm -rf node_mdoules/ && npm i

Tôi sẽ giữ câu hỏi này, vì nó có thể hữu ích cho những người khác đang gặp lỗi này. Tại thời điểm viết bài này, lỗi vẫn có thể tái hiện trong jsfiddle.

Nếu ai đó tìm ra cách tái hiện nó một cách đáng tin cậy, hãy cung cấp một kho lưu trữ vì tôi biết một vài lập trình viên đam mê đủ tò mò để tìm nguyên nhân gốc rễ của nó.


Câu hỏi ban đầu

Tôi có đoạn mã JavaScript này, nó hoạt động:

const iconsMap = new Map([
  ['Roofs', 'roofs'],
  ['Walls', 'walls'],
  ['Windows & Doors', 'doors'],
  ['Heating & Controls', 'heating'],
  ['Ventilation & Air Tightness', 'ventilation'],
  ['Renewables', 'renewables'],
  ['Others', 'others'],
  ['Default', 'home'],
]);

console.log(
  Object.assign({}, ...Array.from(iconsMap).map(([label, fileName]) => ({[label]: fileName})))
);

Lần thử đầu tiên với Typescript của tôi rất gần với JS gốc:

const iconsMap: Map<string, string> = new Map([
      ['Roofs', 'roofs'],
      ['Walls', 'walls'],
      ['Windows & Doors', 'doors'],
      ['Heating & Controls', 'heating'],
      ['Ventilation & Air Tightness', 'ventilation'],
      ['Renewables', 'renewables'],
      ['Others', 'others'],
      ['Default', 'home'],
    ]);
    
interface Dictionary<T> {
  [key: string]: T;
}

console.log(
  Object.assign(
    {} as Dictionary<string>,
    ...Array.from(iconsMap).map(
      ([label, fileName]) => ({ [label]: fileName })
    )
  )
);

Nhưng nó phá vỡ với:

VM325:13 Lỗi Cú pháp Không bắt được: Ký tự '(' không mong đợi tại new Function() tại exec (VM319 typescript.js:41)

Vì lý do nào đó, return ngầm định của hàm mũi tên () => ({}) không hoạt động ở đây. Tôi cần làm () => { return {}; }. Vậy nên điều này hoạt động:

console.log(
  Object.assign(
    {} as Dictionary<string>,
    ...Array.from(iconsMap).map(([label, fileName]) => {
      return { [label]: fileName };
    })
  )
);

Có ai có thể giải thích tại sao không?

Lưu ý: Tôi không quan tâm đến các cách thay thế để viết lại đoạn mã trên (nó thực ra được lấy ra khỏi bối cảnh để làm nổi bật vấn đề). Tôi đã viết lại toàn bộ, tôi đang sử dụng .reduce() và tôi khá hài lòng với nó.
Dành cho những người tò mò... cripter, triển khai thực tế:

export const iconRegistry: Dictionary<string> = Array.from(iconsMap)
  .reduce((o, [label, fileName]) => ({
    ...o,
    [label]: require(`./assets/icons/measure/${fileName}.svg`)
  }), {} as Dictionary<string>);

Nhưng tôi muốn hiểu tại sao return ngầm định lại thất bại ở trên.

Cảm ơn bạn đã dành thời gian.

Câu trả lời #1

Mã bạn có biên dịch mà không gặp bất kỳ lỗi nào

Thêm

Đối với bất kỳ cú pháp JavaScript hợp lệ nào, bạn sẽ không bao giờ nhận được lỗi cú pháp nếu bạn chỉ sao chép và dán nó vào một tệp TypeScript. Bởi vì TypeScript về cú pháp là một tập hợp siêu bậc nghiêm ngặt của cú pháp JavaScript

Câu trả lời #2

Mã TypeScript của bạn hợp lệ và nó được biên dịch sang JS đúng cách, ít nhất là trong TS 3.9.2. Có vẻ như đây là lỗi của jsfiddle hoặc lỗi của TS? Họ sử dụng TS 1.7.3 trong jsfiddle mà bạn liên kết, bạn có thể xác minh bằng cách thực thi ts.version trong bảng điều khiển devtools.

Tôi đã thêm một điểm dừng log trong tập lệnh mà họ sử dụng để chuyển đổi TS sang JS, trông như sau:

var transpiled = ts.transpile.apply(ts, [param[0], param[1], "filename", diagnostics]);
new Function(transpiled)();

Ghi lại biến transpiled cho thấy mã đã được chuyển đổi thành như sau:

var iconsMap = new Map([
    ['Roofs', 'roofs'],
    ['Walls', 'walls'],
    ['Windows & Doors', 'doors'],
    ['Heating & Controls', 'heating'],
    ['Ventilation & Air Tightness', 'ventilation'],
    ['Renewables', 'renewables'],
    ['Others', 'others'],
    ['Default', 'home'],
]);
console.log(Object.assign({}, ...Array.from(iconsMap).map(function ([label, fileName]) ({ [label]: fileName }))));

Lưu ý rằng hàm mũi tên đã được chuyển thành:

function ([label, fileName]) ({ [label]: fileName })))

Điều này, tất nhiên, là không hợp lệ. Tôi gợi ý bạn nên sử dụng một công cụ như Quokka trong vscode hoặc ts-node nếu bạn muốn có một môi trường thử nghiệm cục bộ để thử nghiệm mà không cần phải thiết lập nhiều, nhưng bạn có thể, ít nhất, kiểm soát được phiên bản TS mà bạn đang thử.