node.js - fel TS2300: Dubbel identifierare 'string' när jag migrerar min Nodejs-kod till TypeScript


Jag migrerar ett Nodejs-projekt till TypeScript. Började från index.js, ändrade det till index.ts och gjorde de nödvändiga ändringarna för ts. Men nu stöter jag på felet

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

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

Jag har försökt med de flesta svaren på det förvirrande "duplicate identifier" TypeScript-felmeddelandet men de fungerade alla inte för mig, vilket inkluderar:

  1. npm install @types/node --save-dev och lägg till "typeRoots": ["node_modules/@types"]
  2. installera om node_modules-mappen
  3. leka med compilerOptions

Detta är min 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"]
}

Jag installerade inte @types/express men enligt https://github.com/Microsoft/TypeScript/issues/247, "Om ett modul inte har typdata tillgänglig (via en .d.ts-fil), måste man använda CommonJS-alternativet istället för ES6-modulsyntaxen". Det verkar fungera, så jag blandar require med import i min kod.

Kunde detta vara orsaken?

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

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

--- uppdatering ---

Bortsett från svaret @Jared Smith gav, tycker jag att typade funktionsparametrar som använder destrukturering och rest i TypeScript ger mer detaljerad information.

Svar #1

Du kan inte bara lägga till typanteckningar i funktionsparameterns destrukturering på det sättet. Ändra din kod till detta:

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

Här i signaturen för callback-funktionen har vi den vanliga destrukturdelen { user_id }, men parametern till den funktionen är fortfarande ett objekt med en user_id-egenskap och måste typas som sådan. Jag kommer att skriva om det nedan med typen extraherad och parametern icke-destrukturerad för att kanske hjälpa till att ge idén:

type User = {
  user_id: string
}

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

Detta motsvarar den ovanstående inbäddade versionen och det finns ingen syntaktisk genväg.