1

I have a general function for wrapping anything to an array:

const ensureArray = <T,>(value?: T | T[]): T[] => {
  if (Array.isArray(value)) return value
  if (value === undefined) return []
  return [value]
}

const undef = undefined
ensureArray(undef) // result type undefined[]

const str = 'string'
ensureArray(str)  // result type string[]

const strArray = ['string']
ensureArray(strArray)  // result type string[]

interface Interface {
  [key: string]: string | string[] | number | number[]
}
const p:Interface ={a:'x'}
ensureArray(p.a)  
// types as const ensureArray: <string | number>(value?: string | number | (string | number)[] | undefined) => (string | number)[]

Is there a way to make the TypeScript deduce the function type as

(value: string | number | string[] | number[] | undefined) => string[] | number[]

?

Fiddle with the example: https://www.typescriptlang.org/play?#code/MYewdgzgLgBAppArgJzgQWcghgTxgXhgB4AVAGgD4AKANywBtE4B+ALhhJgB8OBtAXQCU7EgIIUYAbwBQMGAEsAZjCoZsOAHTyIa3LQZNBgmKigowMOoziyFy-dYL5CiMABM4i+WDhvjp8xgBWwDkC14rJn5pAF9paVBIWFcPZRd3T29faQQIFHRMPRTPQXjE6BhoZAIYAHIq7wBzWpykVF0cKirShPAKqo6a3nqoZCba6Nz8jq7Rjp7vKDhkRSxgOBgASTAllbWNmTleAGs4HHYGsEb+C9Gm7kq7q7EeMEQAWwAjZYe3r+XgnFyrAAA6sba7VbrAiSLCsWoAD1qcSm7UKnRBGiwpSAA

1 Answer 1

2

I would add an overload to the function where the return type is a conditional type.

function ensureArray<T,>(value?: T | T[]): T extends any[] ? T : T[]
function ensureArray<T,>(value?: T | T[]): T[] {
  if (Array.isArray(value)) return value
  if (value === undefined) return []
  return [value]
}

We can check if T is an array type. If it is, just return it. If not, return T[]. The overload will stop TypeScript from complaining about the return statements in the actual implementation.


Playground

Sign up to request clarification or add additional context in comments.

1 Comment

Looks good, thanks. Maybe small modification: function ensureArray<T,>(value?: T): T extends any[] ? T : T[] function ensureArray<T,>(value?: T | T[]): T[] { if (Array.isArray(value)) return value if (value === undefined) return [] return [value] }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.