adaltas/node-http-status

Modify interface typing

doong-jo opened this issue · 6 comments

Hello, Thanks for your great work.

I followed up your example.

const status = require('http-status');
 
console.info(status.INTERNAL_SERVER_ERROR);
// Output: 500
 
console.info(status[500]);
console.info(status[status.INTERNAL_SERVER_ERROR]);
// Both output: "Internal Server Error"
 
console.info(status['500_NAME']);
console.info(status[`${status.INTERNAL_SERVER_ERROR}_NAME`]);
// Both output: "INTERNAL_SERVER_ERROR"
 
console.info(status['500_MESSAGE']);
console.info(status[`${status.INTERNAL_SERVER_ERROR}_MESSAGE`]);
// Both output: "A generic error message, given when an unexpected condition was encountered and no more specific message is suitable."
 
console.info(status['500_CLASS']);
console.info(status[`${status.INTERNAL_SERVER_ERROR}_CLASS`]);
// Both output: "5xx"

but I met the error below in typescript.

// in typescript
import httpStatus from 'http-status'

httpStatus[httpStatus.BAD_REQUEST] // error
httpStatus[`${httpStatus.BAD_REQUEST}`],  // error
httpStatus[400],  // fine
/* 
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'HttpStatus'.
  No index signature with a parameter of type 'string' was found on type 'HttpStatus'
*/
// in javascript
import httpStatus from 'http-status'

httpStatus[httpStatus.BAD_REQUEST] // fine
httpStatus[`${httpStatus.BAD_REQUEST}`],  // fine

Do you have any other ideas? In my expectation, to fix this, I think the type defined in the interface needs to be modified. Your typing is great. However, I think it should be modified as below so that JavaScript and TypeScript can behave the same in the same code.

export = httpStatus;

declare const httpStatus: httpStatus.HttpStatus;

declare namespace httpStatus {
	
	interface HttpStatus {
          [key:string] : string | number; // like this..
          ...

I have made a test inside ./test/types.ts and it seems to pass:

    it('check #37', () => {
      status[`${status.BAD_REQUEST}`]
      status[400]
    })

This is not a problem at runtime. However, there is a problem in the typescript compilation phase.

You can check by following the instructions below.

  1. create tsconfig.json
// tsconfig.json (project root path)
{
  "compileOnSave": true,
  "compilerOptions": {
    "types": ["jest", "node"],
    "target": "es6",
    "strict": true,
  },
  "exclude": ["node_modules"]
}
  1. npm run test (error occured)

스크린샷 2020-05-01 오전 12 48 00

Removing the attribute("strict: true") doesn't cause any problems, but it's just a way to avoid it.

Note that --strict is enabled by default. This means that you'll automatically be opted into the strict-by-default mode when starting a new TypeScript project.

Is this part that shouldn't be considered?

I tried to make it work but I failed. If any good TypeScript engineer pass by this issue, we will enjoy his help.

ljayz commented

Hello dynamic variable also will generated error

Kindly see the following example

import status from 'http-status';
const code = 404;
const message = status[code]; //error: Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 'HttpStatus'

I follow microsoft/TypeScript#35859 (comment) for a quick workaround but if you can fix the typing issue it would be great

Thank you

Version 1.5.0 hopefully fixes the issue. It did for me @doong-jo original example.