typescript - Hur man returnerar typ baserat på generisk indatatyp?


Jag arbetar på en wrapper för fetch. Jag skulle vilja skapa en generell funktion för alla CRUD (post, get, uppdatera, ta bort) operationer. GET-förfrågan returnerar viss data medan en DELETE-förfrågan kanske inte returnerar någon data.

function fetchIt<T>(path: string, init?: RequestInit | undefined): T {
  // really use fetch
  // ...
  // if T is not provided return null
  //
  // if T is given return a value of type T

  return {} as T
}

interface User {
  name: string
}

// getResult should be of type User because we provided User as input type
const getResult = fetchIt<User>('/users/1')

// deleteResult should be null because we did not provide any input type
const deleteResult = fetchIt('/users')

Här är länken till lekplatsen.

Jag vill inte returnera T | null eftersom jag då alltid måste kontrollera om resultatet är null eller inte.

// this is not what I want
function fetchThis<T>(): T | null {
  return null
}

const a = fetchThis()
const b = fetchThis<User>()

if (b !== null) {
  console.log(b)
}

Jag skulle vilja få null när jag inte tillhandahåller en generisk typ och när jag tillhandahåller en typ ska det vara returvärdet.

Några idéer? Tack så mycket!

Svar #1

Du kanske vill att T själv ska vara null när det inte anges manuellt av anroparen. Om så är fallet kan du använda en generisk parameterstandard med =-syntaxen:

function fetchIt<T = null>(path: string, init?: RequestInit | undefined): T {
  return {} as T; // unsafe assertion, but so is fetch() I guess so 🤷♂️
}

Detta ger dig det beteende du efterfrågar:

const getResult = fetchIt<User>('/users/1');
// const getResult: User
const deleteResult = fetchIt('/users');
// const deleteResult: null

Lekplatslänk till kod

Relaterade artiklar