From a23f0f2dc98e1c2ef8df78cfd9d31e64e302580a Mon Sep 17 00:00:00 2001
From: Jeremy <51220084+jeremy-rifkin@users.noreply.github.com>
Date: Fri, 2 Dec 2022 17:15:55 -0500
Subject: [PATCH] Updated CompilerProps getter typings to be way more awesome

---
 lib/compiler-finder.ts |  6 +++---
 lib/properties.ts      | 41 ++++++++++++++++++++++++++++++++++++++---
 2 files changed, 41 insertions(+), 6 deletions(-)

diff --git a/lib/compiler-finder.ts b/lib/compiler-finder.ts
index b4f068b42..0d5e2f638 100644
--- a/lib/compiler-finder.ts
+++ b/lib/compiler-finder.ts
@@ -410,15 +410,15 @@ export class CompilerFinder {
             this.languages,
             'compilers',
             '',
-            exs => _.compact((exs as string).split(':')) as unknown as PropertyValue,
-        ) as _.Dictionary<any>;
+            exs => _.compact((exs as string).split(':')) as unknown as string[],
+        );
         this.addNdkExes(langToCompilers);
         logger.info('Exes found:', langToCompilers);
         return langToCompilers;
     }
 
     addNdkExes(langToCompilers) {
-        const ndkPaths = this.compilerProps(this.languages, 'androidNdk') as _.Dictionary<any>;
+        const ndkPaths = this.compilerProps(this.languages, 'androidNdk') as unknown as _.Dictionary<any>;
         _.each(ndkPaths, (ndkPath, langId) => {
             if (ndkPath) {
                 const toolchains = fs.readdirSync(`${ndkPath}/toolchains`);
diff --git a/lib/properties.ts b/lib/properties.ts
index d019f4556..995672696 100644
--- a/lib/properties.ts
+++ b/lib/properties.ts
@@ -136,7 +136,7 @@ type LanguageDef = {
 export class CompilerProps {
     public readonly languages: Record<string, any>;
     public readonly propsByLangId: Record<string, PropertyGetter>;
-    public readonly ceProps: any;
+    public readonly ceProps: PropertyGetter;
 
     /***
      * Creates a CompilerProps lookup function
@@ -151,6 +151,9 @@ export class CompilerProps {
         _.each(this.languages, lang => (this.propsByLangId[lang.id] = propsFor(lang.id)));
     }
 
+    $getInternal(base: string, property: string, defaultValue: undefined): PropertyValue;
+    $getInternal<T extends PropertyValue>(base: string, property: string, defaultValue: Widen<T>): typeof defaultValue;
+    $getInternal<T extends PropertyValue>(base: string, property: string, defaultValue?: PropertyValue): T;
     $getInternal(langId: string, key: string, defaultValue: PropertyValue): PropertyValue {
         const languagePropertyValue = this.propsByLangId[langId](key);
         if (languagePropertyValue !== undefined) {
@@ -172,11 +175,43 @@ export class CompilerProps {
      * @param {?function} fn - Transformation to give to each value found
      * @returns {*} Transformed value(s) found or fn(defaultValue)
      */
+    get(
+        base: string | LanguageDef[] | Record<string, any>,
+        property: string,
+        defaultValue?: undefined,
+        fn?: undefined,
+    ): PropertyValue;
+    get<T extends PropertyValue>(
+        base: string | LanguageDef[] | Record<string, any>,
+        property: string,
+        defaultValue: Widen<T>,
+        fn?: undefined,
+    ): typeof defaultValue;
+    get<T extends PropertyValue>(
+        base: string | LanguageDef[] | Record<string, any>,
+        property: string,
+        defaultValue?: PropertyValue,
+        fn?: undefined,
+    ): T;
+
+    get<R>(
+        base: string | LanguageDef[] | Record<string, any>,
+        property: string,
+        defaultValue?: undefined,
+        fn?: (item: PropertyValue, language?: any) => R,
+    ): R;
+    get<T extends PropertyValue, R>(
+        base: string | LanguageDef[] | Record<string, any>,
+        property: string,
+        defaultValue: Widen<T>,
+        fn?: (item: PropertyValue, language?: any) => R,
+    ): typeof defaultValue | R;
+
     get(
         langs: string | LanguageDef[] | Record<string, any>,
         key: string,
         defaultValue?: PropertyValue,
-        fn: (item: PropertyValue, language?: any) => PropertyValue = _.identity,
+        fn?: (item: PropertyValue, language?: any) => unknown,
     ) {
         fn = fn || _.identity;
         if (_.isEmpty(langs)) {
@@ -184,7 +219,7 @@ export class CompilerProps {
         }
         if (!_.isString(langs)) {
             return _.chain(langs)
-                .map(lang => [lang.id, fn(this.$getInternal(lang.id, key, defaultValue), lang)])
+                .map(lang => [lang.id, fn!(this.$getInternal(lang.id, key, defaultValue), lang)])
                 .object()
                 .value();
         } else {
-- 
GitLab