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

typescript - คำจำกัดความประเภทสำหรับฟังก์ชัน 'evolve'


ฉันกำลังพยายามเขียนนิยามชนิดง่าย ๆ สำหรับฟังก์ชัน evolve จาก ramda (https://ramdajs.com/docs/#evolve) นิยามอย่างเป็นทางการใช้ไม่ได้อย่างถูกต้อง

type Transformation<State> = {
  [Key in keyof State]: (x: State[Key]) => any
}

declare function evolve
  <State extends {}, Evolver extends Partial<Transformation<State>>>(evolver: Evolver, state: State):
  {[Key in keyof State]: Evolver[Key] extends (...args: any[]) => {} ? ReturnType<Evolver[Key]> : State[Key]}

ฉันกำลังพยายามใช้สิ่งนั้นในฟังก์ชันทั่วไป:

const foo = <State extends {a: string, b: string}>(state: State) => {
  const test = evolve({
    a: x => x,
    b: x => x
  }, state)
}

แต่ฉันได้รับข้อผิดพลาด:

Argument of type '{ a: (x: State["a"]) => State["a"]; b: (x: State["b"]) => State["b"]; }' is not assignable to parameter of type 'Partial<Transformation<State>>'.(2345)

จากข้อผิดพลาดไม่ชัดเจนว่าทำไมถึงไม่สามารถกำหนดค่าได้ ดังนั้นฉันจึงไม่รู้วิธีแก้ไข

คำตอบ #1

ดูเหมือนว่าจะมีหลายสิ่งเกิดขึ้น ฉันสามารถทำให้สิ่งนี้ทำงานได้โดยการยก Evolver ไว้ในประเภทอ้างอิงของมันเอง ซึ่งยังช่วยหลีกเลี่ยงปัญหาดัชนีเมื่อพยายามระบุว่าเป็นพารามิเตอร์ทั่วไปตัวที่ 2 ฉันยังเปลี่ยนบางประเภทการคืนค่าเป็น unknown เพื่อให้ ts ตรวจสอบโดยอัตโนมัติในวัตถุ evolver

type Transformation<T> = {
  [K in keyof T]: (x: T[K]) => unknown;
};

type Evolver<State> = Partial<Transformation<State>>;

declare function evolve<State extends { [key: string]: unknown }>(
  evolver: Evolver<State>,
  state: State
): {
  [Key in keyof State]: Evolver<State>[Key] extends (...args: any[]) => infer R
    ? R
    : State[Key];
};

const foo = (state: { a: string; b: string }) => {
  const test = evolve(
    {
      a: (x) => x,
      b: (x) => x,
    },
    state
  );
};

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