ค้นหาเว็บไซต์

node.js - TSNode + Mocha: เพิกเฉยต่อข้อผิดพลาดของ TypeScript (ทำให้คอมไพเลอร์สร้างโค้ดแม้มีข้อผิดพลาดและทำให้ TSNode รันโค้ดที่ถูกสร้าง)


ในโค้ดด้านล่าง แม้ว่าฟังก์ชัน test2 จะไม่ถูกต้อง แต่ก็ไม่ควรมีผลต่อการทดสอบฟังก์ชัน test1:

export function test1(): boolean {
  return true;
}

export function test2(): number {
  return "1";
}

ทดสอบ :

import { assert as Assert } from "chai";
import { test1 } from "./example";


describe("Example", (): void => {
  it("Example", (): void => {
    Assert.isTrue(test1());
  });
});

อย่างไรก็ตาม Mocha ที่รันโดย TSNode จะล้มเหลว:

TSError: ⨯ Unable to compile TypeScript:
Source/ProjectBuilder/example.ts(6,3): error TS2322: Type '"1"' is not assignable to type 'number'.

เป็นไปได้ไหมที่จะบังคับให้ TSNode ทำการทดสอบข้างต้นให้เสร็จ? TypeScript มีตัวเลือก noEmitOnError...

mocharc.yaml ของฉัน:

extension:
  - ts
spec: "**/*.test.ts"
require:
  - ts-node/register
  - tsconfig-paths/register

ทำไมฉันถึงต้องการมัน

ตาม สถาปัตยกรรมสะอาด "กฎทางธุรกิจต้องไม่พึ่งพาสิ่งใด ๆ และต้องสามารถทดสอบได้" แต่แม้ว่ากฎทางธุรกิจจะไม่พึ่งพา views, controllers ฯลฯ เราก็ไม่สามารถทดสอบมันได้หากมีข้อผิดพลาดใน views, controllers ฯลฯ อยู่

เมื่อฉันแก้ไขตรรกะทางธุรกิจในแอปพลิเคชันของฉัน สิ่งที่ขึ้นอยู่กับมันทั้งหมดจะกลายเป็นโมฆะ สมมติว่าในเอนทิตีของฉันในตรรกะธุรกิจ type User { name: string; age: number } ได้ถูกเปลี่ยนเป็น type User { fullName: string; age: string; } สิ่งที่ขึ้นอยู่กับตรรกะธุรกิจทั้งหมด (มุมมอง ตัวควบคุม ผู้เสนอ ฯลฯ) จะกลายเป็นโมฆะ - ฉันจึงจำเป็นต้องแก้ไขมันด้วยตามการปรับปรุงตรรกะธุรกิจ

// In business rules:

type User = { 
  ID: number;
  fullName: string; 
  age: string; // in past - number
}

// In controller:

class UserProfileController {
  // ...
  // All what comes from input field is string    ↓
  private onClickChangeUserAge(inputtedUserAge: string) {
    // This expression obeys to previous version of business rules!
    this.targetUser.age = Number(inputtedUserAge);
    // TypeScript will emit type error, when I try to test business rules,
    // however business rules does not depend on controller.
  }
}

อย่างไรก็ตาม ในแอปพลิเคชันขนาดใหญ่ การแก้ไขเหล่านี้อาจใช้เวลาหลายวัน หลายสัปดาห์ หรือหลายเดือน เราจะได้รับข้อเสนอแนะที่พิสูจน์ได้อย่างไรว่าอย่างน้อยตรรกะทางธุรกิจก็ทำงานอย่างถูกต้องและเราอยู่ในเส้นทางที่ถูกต้อง?

คำตอบ #1

มันไม่มีเหตุผลเลยที่คุณจะขอให้ Typescript ไม่สนใจประเภท สิ่งที่คุณกำลังอธิบายนั้นคล้ายกับการขอเครื่องคิดเลขที่ยืนยันว่า 2 + 2=5 เพียงชั่วคราว เพราะในที่สุดคุณจะขอให้ 2 + 3=5 แต่สิ่งนั้นอาจใช้เวลานานมาก

สมมติฐานในคำถามของคุณคือ number และ string มีความเข้ากันได้เพียงพอที่ตรรกะทางธุรกิจของคุณจะถูกต้องไม่ว่าจะ test2 คืนค่า 1 หรือ "1" ซึ่งนี่ไม่เป็นความจริง: ยกตัวอย่างเช่น 1 + 1 == 2, "1" + 1 == "11", และ "1" - 1 == 0 ขึ้นอยู่กับว่าอันไหนใช้กับกรณีของคุณ การไม่สนใจชนิดข้อมูลอาจทำให้คุณทดสอบตรรกะทางธุรกิจได้ หรืออาจทำให้คุณมั่นใจโดยผิดพลาดในระบบที่เสียหายก็ได้ ผมขอสรุปอย่างคร่าวๆ ว่าโดยทั่วไปชนิดข้อมูลถือเป็นส่วนหนึ่งของตรรกะทางธุรกิจที่คุณพยายามตรวจสอบ--โมเดลข้อมูลจะถือเป็นอะไร หากไม่ใช่ตรรกะทางธุรกิจ?

แทนที่จะเป็นเช่นนั้น สิ่งที่คุณกำลังอธิบายคือ การย้ายข้อมูลอย่างค่อยเป็นค่อยไป ซึ่งกฎของธุรกิจจะทำให้แน่ใจว่า test2 คืนค่า string | number โดยการอธิบายการย้ายข้อมูลอย่างแม่นยำในระบบประเภท คุณอาจสามารถยืนยันได้ว่าตรรกะทางธุรกิจถูกต้อง--หากเป็นจริงตลอดการย้ายข้อมูลของคุณ--และยังสามารถให้ประเภทที่คุณสามารถใช้ได้เฉพาะจากโมดูลและจุดเรียกบางจุดที่สามารถปรับให้เข้มงวดขึ้นเมื่อคุณทำการย้ายข้อมูลเสร็จ.

คำตอบ #2

type User = { 
  ID: number;
  fullName: string; 
  age: string | number
}

คุณสามารถระบุทั้งสองประเภทเพื่อให้ง่ายต่อการย้ายและไม่ต้องใช้ //@ts-ignore ทุกที่

นี่จะเพิ่มคำแนะนำที่ถูกต้องทุกที่ เช่น:

บทความที่เกี่ยวข้อง