How to use webdirverio in typescript project, or please provide high level overview of how to refer to types defined in imported packages

Viewed 244

This is the specific case I've been working on, below it, further down, is the original more general question.

  • I'm trying to create a private npm package for e2e testing of a website.

  • I need to use the webdriverio package.

  • I want the user to be able to start my executable with a provided configuration, one part of this configuration must be a webdriverio config (actually a subset of it, since I'd like to restrict some options). The other part of the configuration is related to my package: user login name etc.

To achieve this, I've declared my own type and expect the user's argument to conform to it.

But the problem is that when I try to compile the code, which declares that type, I get errors like:

Argument of type '{ … } is not assignable to parameter of type 'RemoteOptions'

Types of property 'logLevel' are incompatible

Type 'string' is not assignable to type 'WebDriverLogTypes | undefined'.

The code, which declares that type is (I left the comments just to demonstrate attempts I'd tried to fix this):

//import { WebdriverIO } from '@wdio/types';

type TestUserConfig = {
  //wdioConfig: WebdriverIO,
  wdioConfig: {
    path: '/wd/hub',
    automationProtocol: 'webdriver',
    //logLevel: 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent',
    logLevel: string,
    waitforTimeout: number,
    capabilities: {
      browserName: 'chrome',
    },
  },
  domain: string,
  userLogin: string,
  userPassword: string,
  googleAuthSecret: string,
  expectedRole: string,
}

export type {
  TestUserConfig,
}

The problem is that if I try to refer to those webdriverio types directly, like:

logLevel: WebDriverLogTypes,

I get errors like Cannot find name 'WebDriverLogTypes'

If I try to import that type like:

import {WebDriverLogTypes} from '@wdio/types';

I ger errors like: Module '"@wdio/types"' has no exported member 'WebDriverLogTypes'


The original question:

Suppose there is a nodejs package (I won't call it module, since I mean a module, but not a module of mine, which is under my control, but a module installed via npm). That package exports a function, which expects certain type as its argument:

type Foo = 'foo';
export default function otherModule(arg: Foo) {}

Now, when I use this module, I want typescript to correctly catch type errors, so that an attempt to compile this TypeScript code throws an error:

import otherModule from 'other-module';
otherModule('bar');

What would be the commonly accepted (probably the best) approach to achieve this?


I've seen some packages have '@types/*' packages too, but I haven't been able to figure out how to use them.

1 Answers

A general approach to use types for other imported libraries/packages etc.:

If the imported library has been developed in JavaScript it, most likely, doesn't have any type definitions out of the box, so in this case there are only these solutions:

  • check if there is a type definition for this library (usually it may be the '@types/{libraryName}' package or something else, if it's provided in the library docs.
  • create a type declaration yourself for this library: see the Ambient declarations in the TypeScript docs.

Then import that declaration and use it to refer to types from that library.


For my specific case with webdriverio, I've ended up with the next solution.

Since webdriverio is apparently developed with TypeScript it already has its own type declarations.

So I just looked into the @wdio/types package to see where is that WebDriverLogTypes type had been declared and used that namespace to reference that type:

import type { Options } from '@wdio/types';

type TestUserConfig = {
  wdioConfig: {
    path: '/wd/hub',
    automationProtocol: 'webdriver',
    logLevel: Options.WebDriverLogTypes,
    waitforTimeout: number,
    capabilities: {
      browserName: 'chrome',
    },
  },
  domain: string,
  userLogin: string,
  userPassword: string,
  googleAuthSecret: string,
  expectedRole: string,
}

export type {
  TestUserConfig,
}
Related