From cf1b29280dc0dc27717fd58d06823687d21014b7 Mon Sep 17 00:00:00 2001
From: Jeremy <51220084+jeremy-rifkin@users.noreply.github.com>
Date: Sun, 4 Dec 2022 00:58:58 -0500
Subject: [PATCH] Updated CompilerProps.get typing

---
 lib/options-handler.ts | 14 +++++-----
 lib/properties.ts      | 61 ++++++++++++++++++++++++++++++++++--------
 2 files changed, 57 insertions(+), 18 deletions(-)

diff --git a/lib/options-handler.ts b/lib/options-handler.ts
index 0210b380b..d0c3b7268 100755
--- a/lib/options-handler.ts
+++ b/lib/options-handler.ts
@@ -68,10 +68,10 @@ type OptionsType = {
     libs: Record<any, any>;
     remoteLibs: Record<any, any>;
     tools: Record<any, any>;
-    defaultLibs: string;
-    defaultCompiler: string;
-    compileOptions: string;
-    supportsBinary: boolean;
+    defaultLibs: Record<LanguageKey, string>;
+    defaultCompiler: Record<LanguageKey, string>;
+    compileOptions: Record<LanguageKey, string>;
+    supportsBinary: Record<LanguageKey, boolean>;
     supportsExecute: boolean;
     supportsLibraryCodeFilter: boolean;
     languages: Record<string, any>;
@@ -110,10 +110,10 @@ type OptionsType = {
 export class ClientOptionsHandler {
     compilerProps: CompilerProps['get'];
     ceProps: PropertyGetter;
-    supportsBinary: boolean;
-    supportsExecutePerLanguage: boolean;
+    supportsBinary: Record<LanguageKey, boolean>;
+    supportsExecutePerLanguage: Record<LanguageKey, boolean>;
     supportsExecute: boolean;
-    supportsLibraryCodeFilterPerLanguage: boolean;
+    supportsLibraryCodeFilterPerLanguage: Record<LanguageKey, boolean>;
     supportsLibraryCodeFilter: boolean;
     remoteLibs: Record<any, any>;
     options: OptionsType;
diff --git a/lib/properties.ts b/lib/properties.ts
index 6dbb8c299..feed9c0f1 100644
--- a/lib/properties.ts
+++ b/lib/properties.ts
@@ -27,6 +27,8 @@ import path from 'path';
 
 import _ from 'underscore';
 
+import {LanguageKey} from '../types/languages.interfaces';
+
 import {logger} from './logger';
 import {PropertyGetter, PropertyValue, Widen} from './properties.interfaces';
 import {toProperty} from './utils';
@@ -175,37 +177,74 @@ export class CompilerProps {
      * @param {?function} fn - Transformation to give to each value found
      * @returns {*} Transformed value(s) found or fn(defaultValue)
      */
+
+    // A lot of overloads for a lot of different variants:
+    // const a = this.compilerProps(lang, property); // PropertyValue
+    // const b = this.compilerProps<number>(lang, property); // number
+    // const c = this.compilerProps(lang, property, 42); // number
+    // const d = this.compilerProps(lang, property, undefined, (x) => ["foobar"]); // string[]
+    // const e = this.compilerProps(lang, property, 42, (x) => ["foobar"]); // number | string[]
+    // if more than one language:
+    // const f = this.compilerProps(languages, property); // Record<LanguageKey, PropertyValue>
+    // const g = this.compilerProps<number>(languages, property); // Record<LanguageKey, number>
+    // const h = this.compilerProps(languages, property, 42); // Record<LanguageKey, number>
+    // const i = this.compilerProps(languages, property, undefined, (x) => ["foobar"]); // Record<LanguageKey, string[]>
+    // const j = this.compilerProps(languages, property, 42, (x) => ["foobar"]);//Record<LanguageKey, number | string[]>
+
+    // general overloads
+    get(base: string, property: string, defaultValue?: undefined, fn?: undefined): PropertyValue;
+    get<T extends PropertyValue>(
+        base: string,
+        property: string,
+        defaultValue: Widen<T>,
+        fn?: undefined,
+    ): typeof defaultValue;
+    get<T extends PropertyValue>(base: string, property: string, defaultValue?: PropertyValue, fn?: undefined): T;
+    // fn overloads
+    get<R>(
+        base: string,
+        property: string,
+        defaultValue?: undefined,
+        fn?: (item: PropertyValue, language?: any) => R,
+    ): R;
+    get<T extends PropertyValue, R>(
+        base: string,
+        property: string,
+        defaultValue: Widen<T>,
+        fn?: (item: PropertyValue, language?: any) => R,
+    ): typeof defaultValue | R;
+    // container base general overloads
     get(
-        base: string | LanguageDef[] | Record<string, any>,
+        base: LanguageDef[] | Record<string, any>,
         property: string,
         defaultValue?: undefined,
         fn?: undefined,
-    ): PropertyValue;
+    ): Record<LanguageKey, PropertyValue>;
     get<T extends PropertyValue>(
-        base: string | LanguageDef[] | Record<string, any>,
+        base: LanguageDef[] | Record<string, any>,
         property: string,
         defaultValue: Widen<T>,
         fn?: undefined,
-    ): typeof defaultValue;
+    ): Record<LanguageKey, typeof defaultValue>;
     get<T extends PropertyValue>(
-        base: string | LanguageDef[] | Record<string, any>,
+        base: LanguageDef[] | Record<string, any>,
         property: string,
         defaultValue?: PropertyValue,
         fn?: undefined,
-    ): T;
-
+    ): Record<LanguageKey, T>;
+    // container base fn overloads
     get<R>(
-        base: string | LanguageDef[] | Record<string, any>,
+        base: LanguageDef[] | Record<string, any>,
         property: string,
         defaultValue?: undefined,
         fn?: (item: PropertyValue, language?: any) => R,
-    ): R;
+    ): Record<LanguageKey, R>;
     get<T extends PropertyValue, R>(
-        base: string | LanguageDef[] | Record<string, any>,
+        base: LanguageDef[] | Record<string, any>,
         property: string,
         defaultValue: Widen<T>,
         fn?: (item: PropertyValue, language?: any) => R,
-    ): typeof defaultValue | R;
+    ): Record<LanguageKey, typeof defaultValue | R>;
 
     get(
         langs: string | LanguageDef[] | Record<string, any>,
-- 
GitLab