TypeScript גנרי עם תנאי מעריך סוגי איחוד בנפרד


אני מנסה ליצור טיפוס TypeScript שייצג או VoidFunction או פונקציה עם פרמטר יחיד על בסיס גנרי מסופק.

באמצעות מצב תנאי, הסוג נראה כך:

type VoidFunctionOrWithParams<Params> = Params extends void
    ? VoidFunction
    : (params: Params) => void;

שימוש לדוגמה עשוי להיראות כך:

type WithStringParams = VoidFunctionOrWithParams<'one' | 'two'>;

סוג התוצאה הצפוי

(params: 'one' | 'two') => void

סוג התוצאה בפועל

((params: "one") => void) | ((params: "two") => void)

מדוע TypeScript מפרש זאת כשתי פונקציות נפרדות ללא חפיפה? האם יש דרך לעקוף זאת? מה שאני באמת רוצה הוא סוג פונקציה אחת שבו params יכול להיות כל אחד מהערכים באיחוד - ולא סוגי פונקציות שונים.

תשובה #1

אתה רואה כאן את ההשפעות של סוגים מפיצים מותנים. כדי להימנע מהפצה, אתה יכול לעטוף את סוג הגנרי בתוך טופל.

type VoidFunctionOrWithParams<Params> = [Params] extends [void]
    ? VoidFunction
    : (params: Params) => void;

type WithStringParams = VoidFunctionOrWithParams<'one' | 'two'>;
// type WithStringParams = (params: "one" | "two") => void

מִגרָשׂ מְשָׂחָק