Sherif eldeeb
Sherif eldeeb

Reputation: 2226

how to make a property optional but not undefined in typescript

when you create a typescript interface with an optional property like this:

interface X {
 a?: string
}

here x.a is of type string | undefined so typescript will complain of the following code:

function stringValue(value: string):void{}
function test(x:X){
 // error, because stringValue() only accepts strings
 stringValue(x.a)
}

but, if Typescript knows x.a value in advance, why it still complains?

function test(x:X){
  x = { a:"string value" }
  // now x.a is string, not string | undefined
  // so the following code must be valid
  // but TS still complains

  stringValue(x.a)
  
  // this is a workaround but out of my question's scope
  stringValue(x.a as string)
}

how to tell typescript that the consumer of our function doesn't have to provide a value for x.a but we assign a default value to it, so it cannot be an undefined.

Upvotes: 2

Views: 2023

Answers (1)

JosephDaSilva
JosephDaSilva

Reputation: 1197

TypeScript does not narrow down the type of x when a new object with a property a that is definitely not undefined is assigned to it. Its type remains X, and that is why you get the error.

This compiles, but it mutates x:

function test(x: X) {
    x.a = "string value";
    stringValue(x.a);
}

But this is probably not what you want: you are not assigning a default value for x.a, instead, you are replacing the value of x.a that you get from the argument. In other words, your test function is the same as calling stringValue("string value").

The correct way to provide a default value would be:

function test(x: X) {
    stringValue(x.a ?? "string value");
}

Upvotes: 2

Related Questions