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

javascript - วิธีแก้ข้อผิดพลาด: อาร์กิวเมนต์แบบกระจายต้องมีชนิดเป็นทูเพิลหรือถูกส่งไปยังพารามิเตอร์แบบเหลือ


ฉันกำลังพัฒนาคลาส wrapper ซึ่งสามารถเรียกใช้เมธอดของอินสแตนซ์ภายในด้วยอาร์กิวเมนต์เป็นสตริง

โค้ดทั้งหมดมีดังด้านล่าง

class Inner {
  public prop1: string = 'publicProp';
  private prop2: string = 'privateProp';

  method1(param1: string) {
    console.log(`${param1}`);
  }
  method2(param1: number, param2: number) {
    console.log(`${param1}, ${param2}`);
  }
}

ชั้นเรียนนี้เป็นชั้นเรียนต้นฉบับที่มีฟังก์ชันหลัก

type Fn = (...args: any) => any;

นี่คือประเภทที่จำเป็นด้านล่าง

class Outer {
  private inner = new Inner();

  // I want proxy's second parameter's type will be changed according to first parameter's value
  public proxy<
    // F type is callable member's key
    F extends keyof {
      [K in keyof Inner as Inner[K] extends Fn ? K : never]: any;
    },
    // P type will be changed according to first argument type.
    P extends Parameters<Inner[F]>,
  >(name: F, ...args: P) {
    const fn = this.inner[name];
    if (typeof fn === 'function') {
      // This is right pain point!!
      // TS2556: A spread argument must either have a tuple type or be passed to a rest parameter.
      fn(...args);
    }
  }
}

ส่วนของ fn(...args) ยังคงแสดงข้อผิดพลาดเหมือนด้านบน ผมคิดว่า args ควรถูกสรุปเป็นทูเพิลเพราะเราแจ้งให้คอมไพเลอร์ทราบว่า ประเภทของ args จะถูกขยายโดย Parameter<Inner[F]> ผมจะแก้ไขอย่างไรได้บ้าง?

const outer = new Outer().proxy;
// IDE can infer parameter's type from second parameter
outer('method1', 'stringArg');
outer('method2', 1, 2);

อีกหนึ่งปัญหาคือ IDE สามารถสรุปประเภทของพารามิเตอร์ตามอาร์กิวเมนต์ตัวแรกได้ (ภาพสแนปชอตจริงของ IDE แนบมาด้านล่าง)

ขอบคุณล่วงหน้าสำหรับคำตอบของคุณ! :)