Home > Blockchain >  error TS2300: Duplicate identifier 'string' when migrating my Nodejs code to TypeScript
error TS2300: Duplicate identifier 'string' when migrating my Nodejs code to TypeScript

Time:11-26

I am migrating a Nodejs project to TypeScript. Starting from index.js, changed it to index.ts and did the necessary change for ts. But now I hit the error

src/index.ts:34:90 - error TS2300: Duplicate identifier 'string'.

34   socket.on('login', async function ({ user_id:string}) {...}

I have tried most of answers in Confusing "duplicate identifier" Typescript error message but they all failed to work for me, which includes:

  1. npm install @types/node --save-dev and add "typeRoots": ["node_modules/@types"]
  2. re-install node_modules folder
  3. mess with compilerOptions

This is my tsconfig.json

{
  "compilerOptions": {
    "target": "es2016",
    "module": "commonjs",
    // "typeRoots": ["node_modules/@types"], /* turn it on/off makes no difference */
    "allowJs": true,
    "sourceMap": true,
    "outDir": "./build",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true 
    // "skipDefaultLibCheck": true, /* turn it on/off makes no difference */            
    "skipLibCheck": true   
  },
  "files": ["src/index.ts"], /*I only want to tsc this file*/
  "exclude": ["node_modules"]
}

I did not install @types/express but according to https://github.com/Microsoft/TypeScript/issues/247, "If a module doesn't have type data available (via a .d.ts file), the ES6 module syntax,one must use the CommonJS alternative". It seems to work, so I mix require with import in my codes.

Could this be the reason ?

import { Server, Socket } from "socket.io";

var express = require('express')
var app = express()
var cors = require('cors')
var http = require('http').Server(app)

CodePudding user response:

You can't just add type annotations in function parameter destructuring like that. Change your code to this:

socket.on('login', async function ({ user_id }: { user_id:string }) {...}

Here in the signature for the callback we have the regular destructuring part { user_id } but the parameter to that function is still an object with a user_id property and needs to be typed as such. I'll re-write it below with the type extracted and the parameter non-destructured to maybe help give the idea:

type User = {
  user_id: string
}

socket.on('login', async function (user: User) {
   const user_id = user.user_id;
   // do something
})

This is equivalent to the above inlined version and there isn't a syntactic shortcut.

  • Related