title: Unable to use boolean valued promise as thenable construct in Typescript?
body: <p>I am converting a Protractor page object library from JavaScript to Typescript. I have a static utility method that refreshes until an element is present (or the timeout limit is reached).</p>
  
  <p>For some reason, I am unable to use a <code>boolean</code> valued promise as a <code>thenable</code> construct and I can't figure out why. The error message is <code>error TS2345: Argument of type '(value: boolean) =&gt; Promise&lt;{}&gt; | undefined' is not assignable to parameter of type '((value: boolean) =&gt; {} | IThenable&lt;{}&gt;) | undefined'.
    Type '(value: boolean) =&gt; Promise&lt;{}&gt; | undefined' is not assignable to type '(value: boolean) =&gt; {} | IThenable&lt;{}&gt;'.
      Type 'Promise&lt;{}&gt; | undefined' is not assignable to type '{} | IThenable&lt;{}&gt;'.
        Type 'undefined' is not assignable to type '{} | IThenable&lt;{}&gt;'.</code> </p>
  
  <p>The source code is below with comment showing where the compile error occurs.</p>
  
  <p>I have used this sort of mechanism in the pure JavaScript version of the framework I'm converting to Typescript. What do I need to do to translate this method over to Typescript that will compile?</p>
  
  <pre><code>import {browser, element, ElementFinder, ExpectedConditions} from 'protractor';
  import * as wd from 'selenium-webdriver';
  import {By} from "selenium-webdriver";
  
  export class ExtendedExpectedConditions {
  
      public static refreshUntilElementIsPresent(element: ElementFinder,  numberOfSeconds: number = 30000,
          refreshInterval: number = 5000): void {
          this.refreshElement(element, numberOfSeconds, refreshInterval);
      }
  
      protected static refreshElement(element: ElementFinder, numberOfSeconds: number = 30000, refreshInterval:
          number = 5000) {
  
  
          //This line throws the compile error
          element.isPresent().then(value =&gt; {
              if (!value) {
                  if (numberOfSeconds &lt;= 0) {
                      return new wd.promise.Promise(function (resolve, reject) {
                          reject('Element cannot be found after expected retry numbers');
                      })
                  }
                  browser.sleep(refreshInterval).then(() =&gt; {
                      browser.refresh().then(() =&gt; this.refreshUntilElementIsPresent(element, numberOfSeconds -
                      (refreshInterval / 1000)));
                  });
              }
         });
      }
  }
  </code></pre>
  
  <p>My 'package.json' is below:</p>
  
  <pre><code>{
    "name": "my-project",
    "version": "1.0.0",
    "description": "A test suite",
    "scripts": {
      "tsc": "tsc",
      "pretest": "npm run tsc",
      "test": "node_modules/protractor/bin/protractor tmp/conf.js",
      "start_selenium": "node_modules/protractor/node_modules/webdriver-manager/bin/webdriver-manager start",
      "update_selenium": "node_modules/protractor/node_modules/webdriver-manager/bin/webdriver-manager update"
    },
    "author": aperson@someplace.com,
    "dependencies": {
      "@types/jasmine": "^2.5.52",
      "@types/jasminewd2": "^2.0.2",
      "@types/node": "^7.0.31",
      "any-promise": "^1.3.0",
      "jasmine-reporters": "^2.2.1",
      "protractor": "^5.1.2",
      "typescript": "^2.3.4"
    }
  }
  </code></pre>
  
  <p>My tsconfig.json is below:</p>
  
  <pre><code>{
    "compilerOptions": {
      "target": "es6",
      "module": "commonjs",
      "moduleResolution": "node",
      "sourceMap": true,
      "declaration": false,
      "noImplicitAny": false,
      "outDir": "tmp",
      "types": ["jasmine", "node"],
      "strict": true
    },
    "exclude": [
      "node_modules"
    ]
  }
  </code></pre>
  
  <p>My conf.ts file is below:</p>
  
  <pre><code>import {Config, browser, protractor} from "protractor";
  
  let testsTimeout = 3600000;
  let delayBrowserTimeInSeconds = 0;
  
  export let config: Config = {
      framework: 'jasmine2',
      rootElement: 'body',
      seleniumServerJar:'../node_modules/protractor/node_modules/webdriver-manager/selenium/selenium-server-standalone-3.4.0.jar',
      chromeDriver: '../node_modules/protractor/node_modules/webdriver-manager/selenium/chromedriver_2.30',
      specs: ['tests/*Spec.js'],
      capabilities: {
          browserName: 'chrome',
          acceptSslCerts: true,
          trustAllSSLCertificates: true,
          chromeOptions: {
              args: ['--no-sandbox']
          },
      },
      baseUrl: 'https://www.someurl.com',
  
      jasmineNodeOpts: {
          defaultTimeoutInterval: testsTimeout,
          showColors: true,
          isVerbose: true
      },
  
      onPrepare: () =&gt; {
  
          let origFn = browser.driver.controlFlow().execute;
  
          browser.driver.controlFlow().execute = function () {
              let args = arguments;
  
              origFn.call(browser.driver.controlFlow(), function () {
                  return protractor.promise.delayed(delayBrowserTimeInSeconds * 100);
              });
  
              return origFn.apply(browser.driver.controlFlow(), args);
          };
  
          setTimeout(() =&gt; {
              browser.driver.executeScript&lt;[number, number]&gt;(() =&gt; {
                  return [
                      window.screen.availWidth,
                      window.screen.availHeight
              ];
              }).then((result: [number, number]) =&gt; {
                  browser.driver.manage().window().setSize(result[0], result[1]);
                  browser.driver.manage().window().maximize();
              });
          });
  
      },
  
      getPageTimeout: 120000,
      allScriptsTimeout: testsTimeout
  };
  </code></pre>