diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 7d43e5d..a4374b1 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -20,6 +20,16 @@ Feature suggestions are welcome, but please be aware that:
 
 Below are the guidelines for submitting a pull request.
 
+### Preparations
+
+If you are working on Windows, you may need to enable support for long paths in Git, othwise cloning the submodule may fail. Open an administrator shell, and execute `git config --system core.longpaths true`.
+
+In the cloned repository:
+
+1. `git submodule init`
+2. `git submodule update` (downloading the 3 GB sized TypeScript repository will take a while ...)
+3. `npm install`
+
 ### How to change type definitions
 
 better-typescript-lib replaces the built-in type definitions with its own ones. The renewed definitions are in the `lib/` directory.
@@ -49,7 +59,7 @@ For other declarations, such as type aliases, enums, and namespaces, the replace
 
 ### Committing Build Artifacts
 
-Currently, build artifacts needs to be committed. Follow the following steps to build and commit them.
+Currently, build artifacts need to be committed. Follow the steps below to build and commit them.
 
 1. `npm run build:tsc`
 2. `npm run build:lib`
diff --git a/docs/diff/es5.d.ts.md b/docs/diff/es5.d.ts.md
index 6ae6c9e..c53c76c 100644
--- a/docs/diff/es5.d.ts.md
+++ b/docs/diff/es5.d.ts.md
@@ -793,10 +793,10 @@ Index: es5.d.ts
 -      | undefined
 -      | null,
 -  ): PromiseLike<TResult1 | TResult2>;
-+  then(
-+    onfulfilled?: null | undefined,
-+    onrejected?: ((reason: unknown) => T | PromiseLike<T>) | null | undefined,
-+  ): PromiseLike<T>;
++  then<U>(
++    onfulfilled: (value: T) => U | PromiseLike<U>,
++    onrejected?: ((reason: unknown) => U | PromiseLike<U>) | null | undefined,
++  ): PromiseLike<U>;
 +
 +  /**
 +   * Attaches callbacks for the resolution and/or rejection of the Promise.
@@ -805,9 +805,9 @@ Index: es5.d.ts
 +   * @returns A Promise for the completion of which ever callback is executed.
 +   */
 +  then<U>(
-+    onfulfilled: (value: T) => U | PromiseLike<U>,
++    onfulfilled: ((value: T) => U | PromiseLike<U>) | null | undefined,
 +    onrejected?: ((reason: unknown) => U | PromiseLike<U>) | null | undefined,
-+  ): PromiseLike<U>;
++  ): PromiseLike<T | U>;
  }
  
 -/**
@@ -831,10 +831,10 @@ Index: es5.d.ts
 -      | undefined
 -      | null,
 -  ): Promise<TResult1 | TResult2>;
-+  then(
-+    onfulfilled?: null | undefined,
-+    onrejected?: ((reason: unknown) => T | PromiseLike<T>) | null | undefined,
-+  ): Promise<T>;
++  then<U>(
++    onfulfilled: (value: T) => U | PromiseLike<U>,
++    onrejected?: ((reason: unknown) => U | PromiseLike<U>) | null | undefined,
++  ): Promise<U>;
  
    /**
 +   * Attaches callbacks for the resolution and/or rejection of the Promise.
@@ -843,9 +843,9 @@ Index: es5.d.ts
 +   * @returns A Promise for the completion of which ever callback is executed.
 +   */
 +  then<U>(
-+    onfulfilled: (value: T) => U | PromiseLike<U>,
++    onfulfilled: ((value: T) => U | PromiseLike<U>) | null | undefined,
 +    onrejected?: ((reason: unknown) => U | PromiseLike<U>) | null | undefined,
-+  ): Promise<U>;
++  ): Promise<T | U>;
 +
 +  /**
     * Attaches a callback for only the rejection of the Promise.
@@ -858,9 +858,9 @@ Index: es5.d.ts
 -      | undefined
 -      | null,
 -  ): Promise<T | TResult>;
-+  catch(
-+    onrejected?: ((reason: unknown) => T | PromiseLike<T>) | null | undefined,
-+  ): Promise<T>;
++  catch<U>(
++    onrejected: ((reason: unknown) => U | PromiseLike<U>) | null | undefined,
++  ): Promise<T | U>;
  }
  
  /**
diff --git a/generated/lib.es5.d.ts b/generated/lib.es5.d.ts
index 7dc5a5b..dcbc6cc 100644
--- a/generated/lib.es5.d.ts
+++ b/generated/lib.es5.d.ts
@@ -2095,10 +2095,10 @@ interface PromiseLike<T> {
    * @param onrejected The callback to execute when the Promise is rejected.
    * @returns A Promise for the completion of which ever callback is executed.
    */
-  then(
-    onfulfilled?: null | undefined,
-    onrejected?: ((reason: unknown) => T | PromiseLike<T>) | null | undefined,
-  ): PromiseLike<T>;
+  then<U>(
+    onfulfilled: (value: T) => U | PromiseLike<U>,
+    onrejected?: ((reason: unknown) => U | PromiseLike<U>) | null | undefined,
+  ): PromiseLike<U>;
 
   /**
    * Attaches callbacks for the resolution and/or rejection of the Promise.
@@ -2107,9 +2107,9 @@ interface PromiseLike<T> {
    * @returns A Promise for the completion of which ever callback is executed.
    */
   then<U>(
-    onfulfilled: (value: T) => U | PromiseLike<U>,
+    onfulfilled: ((value: T) => U | PromiseLike<U>) | null | undefined,
     onrejected?: ((reason: unknown) => U | PromiseLike<U>) | null | undefined,
-  ): PromiseLike<U>;
+  ): PromiseLike<T | U>;
 }
 //     /**
 //      * Attaches callbacks for the resolution and/or rejection of the Promise.
@@ -2126,10 +2126,10 @@ interface Promise<T> extends PromiseLike<T> {
    * @param onrejected The callback to execute when the Promise is rejected.
    * @returns A Promise for the completion of which ever callback is executed.
    */
-  then(
-    onfulfilled?: null | undefined,
-    onrejected?: ((reason: unknown) => T | PromiseLike<T>) | null | undefined,
-  ): Promise<T>;
+  then<U>(
+    onfulfilled: (value: T) => U | PromiseLike<U>,
+    onrejected?: ((reason: unknown) => U | PromiseLike<U>) | null | undefined,
+  ): Promise<U>;
 
   /**
    * Attaches callbacks for the resolution and/or rejection of the Promise.
@@ -2138,18 +2138,18 @@ interface Promise<T> extends PromiseLike<T> {
    * @returns A Promise for the completion of which ever callback is executed.
    */
   then<U>(
-    onfulfilled: (value: T) => U | PromiseLike<U>,
+    onfulfilled: ((value: T) => U | PromiseLike<U>) | null | undefined,
     onrejected?: ((reason: unknown) => U | PromiseLike<U>) | null | undefined,
-  ): Promise<U>;
+  ): Promise<T | U>;
 
   /**
    * Attaches a callback for only the rejection of the Promise.
    * @param onrejected The callback to execute when the Promise is rejected.
    * @returns A Promise for the completion of the callback.
    */
-  catch(
-    onrejected?: ((reason: unknown) => T | PromiseLike<T>) | null | undefined,
-  ): Promise<T>;
+  catch<U>(
+    onrejected: ((reason: unknown) => U | PromiseLike<U>) | null | undefined,
+  ): Promise<T | U>;
 }
 // /**
 //  * Represents the completion of an asynchronous operation
diff --git a/lib/lib.es5.d.ts b/lib/lib.es5.d.ts
index b808a5e..329c95a 100644
--- a/lib/lib.es5.d.ts
+++ b/lib/lib.es5.d.ts
@@ -587,10 +587,10 @@ interface PromiseLike<T> {
    * @param onrejected The callback to execute when the Promise is rejected.
    * @returns A Promise for the completion of which ever callback is executed.
    */
-  then(
-    onfulfilled?: null | undefined,
-    onrejected?: ((reason: unknown) => T | PromiseLike<T>) | null | undefined,
-  ): PromiseLike<T>;
+  then<U>(
+    onfulfilled: (value: T) => U | PromiseLike<U>,
+    onrejected?: ((reason: unknown) => U | PromiseLike<U>) | null | undefined,
+  ): PromiseLike<U>;
 
   /**
    * Attaches callbacks for the resolution and/or rejection of the Promise.
@@ -599,9 +599,9 @@ interface PromiseLike<T> {
    * @returns A Promise for the completion of which ever callback is executed.
    */
   then<U>(
-    onfulfilled: (value: T) => U | PromiseLike<U>,
+    onfulfilled: ((value: T) => U | PromiseLike<U>) | null | undefined,
     onrejected?: ((reason: unknown) => U | PromiseLike<U>) | null | undefined,
-  ): PromiseLike<U>;
+  ): PromiseLike<T | U>;
 }
 
 interface Promise<T> extends PromiseLike<T> {
@@ -611,10 +611,10 @@ interface Promise<T> extends PromiseLike<T> {
    * @param onrejected The callback to execute when the Promise is rejected.
    * @returns A Promise for the completion of which ever callback is executed.
    */
-  then(
-    onfulfilled?: null | undefined,
-    onrejected?: ((reason: unknown) => T | PromiseLike<T>) | null | undefined,
-  ): Promise<T>;
+  then<U>(
+    onfulfilled: (value: T) => U | PromiseLike<U>,
+    onrejected?: ((reason: unknown) => U | PromiseLike<U>) | null | undefined,
+  ): Promise<U>;
 
   /**
    * Attaches callbacks for the resolution and/or rejection of the Promise.
@@ -623,18 +623,18 @@ interface Promise<T> extends PromiseLike<T> {
    * @returns A Promise for the completion of which ever callback is executed.
    */
   then<U>(
-    onfulfilled: (value: T) => U | PromiseLike<U>,
+    onfulfilled: ((value: T) => U | PromiseLike<U>) | null | undefined,
     onrejected?: ((reason: unknown) => U | PromiseLike<U>) | null | undefined,
-  ): Promise<U>;
+  ): Promise<T | U>;
 
   /**
    * Attaches a callback for only the rejection of the Promise.
    * @param onrejected The callback to execute when the Promise is rejected.
    * @returns A Promise for the completion of the callback.
    */
-  catch(
-    onrejected?: ((reason: unknown) => T | PromiseLike<T>) | null | undefined,
-  ): Promise<T>;
+  catch<U>(
+    onrejected: ((reason: unknown) => U | PromiseLike<U>) | null | undefined,
+  ): Promise<T | U>;
 }
 
 interface TypedNumberArray<
diff --git a/tests/src/es5.ts b/tests/src/es5.ts
index cf34e39..37a8e66 100644
--- a/tests/src/es5.ts
+++ b/tests/src/es5.ts
@@ -39,8 +39,6 @@ const testPromiseConstructorLike = (MyPromise: PromiseConstructorLike) => {
 };
 // Promise
 const testPromise = (promise: Promise<string>) => {
-  expectType<Promise<string>>(promise.then());
-  expectType<Promise<string>>(promise.catch());
   expectType<Promise<string>>(promise.then(null));
   expectType<Promise<string>>(promise.then(undefined));
   expectType<Promise<string>>(promise.catch(null));
@@ -70,6 +68,14 @@ const testPromise = (promise: Promise<string>) => {
       (err) => Promise.resolve(`${err}`.length),
     ),
   );
+  expectType<Promise<number>>(promise.then(() => 42, () => 42));
+  expectType<Promise<string | number>>(promise.then(null, () => 42));
+  expectType<Promise<string | number>>(promise.then(undefined, () => 42));
+  expectType<Promise<string | number>>(promise.catch(() => 42));
+  // @ts-expect-error
+  promise.then();
+  // @ts-expect-error
+  promise.catch();
   // @ts-expect-error
   promise.then<number>((str: string) => str);
   promise.then<number>(
@@ -78,8 +84,6 @@ const testPromise = (promise: Promise<string>) => {
     () => "NaN",
   );
   // @ts-expect-error
-  promise.then(null, (err) => `${err}`.length);
-  // @ts-expect-error
   promise.catch(null, (err) => `${err}`.length);
 };
 
@@ -525,4 +529,4 @@ expectType<{ foo: number; bar: string; baz: boolean }>(
   }
 }
 
-export {};
+export { };