Skip to content
Advertisement

Get function reference from mssql TYPES object using string

Node.js / mssql / typescript

I’m trying to build a set of input parameters dynamically and add them to a prepared statement. With the code below, the error I get is:

Element implicitly has an ‘any’ type because expression of type ‘string’ can’t be used to index type ‘{ VarChar: ISqlTypeFactoryWithLength; NVarChar: ISqlTypeFactoryWithLength; Text: ISqlTypeFactoryWithNoParams; … 29 more …; Variant: ISqlTypeFactoryWithNoParams; }’.

import { TYPES, PreparedStatement } from 'mssql'
...
const ps = new PreparedStatement(pool);
parameters.forEach((param: IParam) =>{
  let t1 = TYPES[param.dataType]; // ** This doesn't work **
  ps.input(param.name, t1);
  values[param.name] = param.value;
});
...


export interface IParam {
  name: string;
  dataType: string;
  length: number;
  value?: string;
}

Oddly (to me anyway) I can use this code without issue.

  let t1 = TYPES['VarChar'];      // This does work

Any help would be much appreciated.

Answer

Imagine your parameters array looks like:

const parameters: IParam[] = [
    {
        name: "abc",
        dataType: "not_a_valid_data_type",
        length: 4
    }
]

According to the IParam interface you’ve defined, this is a valid input. However, "not_a_valid_data_type" doesn’t exist as a key on the TYPES object. So if TypeScript allowed you to do this, the runtime code would end up being:

let t1 = TYPES["not_a_valid_data_type"];

Which would make the value of t1 be undefined.

In order to use your dataType field as an index, you need to limit it to only be the set of keys on the TYPES object:

type DataType = keyof typeof TYPES; // "VarChar" | "NVarChar" | "Text" | ...

export interface IParam {
  name: string;
  dataType: DataType;
  length: number;
  value?: string;
}

playground link

Advertisement