3
\$\begingroup\$

I am performing a REST API call and I have copied their example code where they show how to perform such an api call. Their example is written in Javascript not Typescript though. To adapt the code I had to create a type type serviceConfig = {[key: string]: any} so that the variable config can be successively appended to.

It is my understanding that any should be avoided where possible. How could I avoid using any in this case?

  • Should I be avoiding coding patterns where I successively append to a variable?
  • Should I instead create a type which describes config more accurately e.g. type serviceConfig = { baseURL?: string, method? string ... etc.}
  • Or is this one of the times where any is acceptable?
import axios from 'axios';
import crypto from 'crypto';
import FormData from 'form-data';


// These parameters should be used for all requests
const SERVICE_APP_TOKEN = process.env.SERVICE_TOKEN!; // Example: sbx:uY0CgwELmgUAEyl4hNWxLngb.0WSeQeiYny4WEqmAALEAiK2qTC96fBad
const SERVICE_SECRET_KEY = process.env.SERVICE_SECRET_KEY!; // Example: Hej2ch71kG2kTd1iIUDZFNsO5C1lh5Gq
const SERVICE_BASE_URL = 'https://api.example.com';

type serviceConfig = {
    [key: string]: any
}

var config: serviceConfig = {}
config.baseURL = SERVICE_BASE_URL;


function createSignature(config: serviceConfig) {
    console.log('Creating a signature for the request...');

    const ts = Math.floor(Date.now() / 1000);
    const signature = crypto.createHmac('sha256', SERVICE_SECRET_KEY);
    signature.update(ts + config.method.toUpperCase() + config.url);

    if (config.data instanceof FormData) {
        signature.update(config.data.getBuffer());
    } else if (config.data) {
        signature.update(config.data);
    }

    config.headers['X-App-Access-Ts'] = ts;
    config.headers['X-App-Access-Sig'] = signature.digest('hex');

    return config;
}


axios.interceptors.request.use(createSignature, function (error) {
    return Promise.reject(error)
})


export function createAccessToken(externalUserId: string, levelName = 'basic-kyc-level', ttlInSecs = 600) {
    console.log("Creating an access token for initializng SDK...");

    var method = 'post';
    var url = `/resources/accessTokens?userId=${externalUserId}&ttlInSecs=${ttlInSecs}&levelName=${levelName}`;

    var headers = {
        'Accept': 'application/json',
        'X-App-Token': SERVICE_APP_TOKEN
    };

    config.method = method;
    config.url = url;
    config.headers = headers;
    config.data = null;

    return config;
}

async function run() {
    const externalUserId = "random-JSToken-" + Math.random().toString(36).substr(2, 9);
    const levelName = 'basic-kyc-level';
    console.log("External UserID: ", externalUserId);
    const response = await axios(createAccessToken(externalUserId, levelName, 1200))
        .then(function (response) {
            console.log("Response:\n", response.data);
            return response;
        })
        .catch(function (error) {
            console.log("Error:\n", error.response.data);
        });
    console.log(response)

}

run();
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

By using any you are losing type safety, which defeats the point of Typescript, at least in this spot. But sometimes it’s just easier.

Just because the example is written in JavaScript doesn’t mean there aren’t types provided for Typescript for the config object. Check the docs and the sources for the correct imports. Or yes, you could define more specific types especially if you are using this in many other places and the API really doesn’t provide types (which seems unlikely in this case). Maybe overkill if this is all there is.

Successive appending - if by that you mean separate statements to assign the properties there is nothing wrong with that, but that’s not what your type means. You could set config to an object literal:

config = { method, url, headers, data: null }

Or even just:

return { method, url, headers, data: null }
\$\endgroup\$
1
  • \$\begingroup\$ Indeed Axios has the AxiosRequestConfig type implemented which I should have been using for my code! github.com/axios/axios/blob/… \$\endgroup\$
    – sev
    Jun 20, 2022 at 22:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.