adaltas / node-http-status

Utility to interact with HTTP status code in Node.js
Other
441 stars 55 forks source link

Modify interface typing #37

Closed doong-jo closed 3 years ago

doong-jo commented 4 years ago

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..
          ...
wdavidw commented 4 years ago

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

    it('check #37', () => {
      status[`${status.BAD_REQUEST}`]
      status[400]
    })
doong-jo commented 4 years ago

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"]
    }
  2. 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.

doong-jo commented 4 years ago

Is this part that shouldn't be considered?

wdavidw commented 4 years ago

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 3 years ago

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 https://github.com/microsoft/TypeScript/issues/35859#issuecomment-587290272 for a quick workaround but if you can fix the typing issue it would be great

Thank you

wdavidw commented 3 years ago

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