TypeScript Question " | " meaning?

Im following a angular tutorial and it uses by default Typescript
Im very Familiar with javascript but i cant figure out what this symbol means

its:

import {Product, products} from '../products';

@Component({
  selector: 'app-product-details',
  templateUrl: './product-details.component.html',
  styleUrls: ['./product-details.component.css']
})

export class ProductDetailsComponent implements OnInit {

  product: Product | undefined;
  /* ... */

its about this part:

product: Product | undefined;

what does this mean?

I know that Product is from a array of objects imported from ‘…/products’
but this part:

| undefined

maybe it means “or undefined”

why would it be undefined since the Product array is there anyways??

I assume that Product is a type or an interface. So

product: Product | undefined;

is saying that on this class there is a property called “product” and the property will have a type of either Product or undefined.

If that doesn’t make sense, could we see the definition of Product?

That make sense and and yes offcourse you can see more

export interface Product {
  id: number;
  name: string;
  price: number;
  description: string;
}

export const products = [
  {
    id: 1,
    name: 'Phone XL',
    price: 799,
    description: 'A large phone with one of the best screens'
  },
  {
    id: 2,
    name: 'Phone Mini',
    price: 699,
    description: 'A great phone with one of the best cameras'
  },
  {
    id: 3,
    name: 'Phone Standard',
    price: 299,
    description: ''
  }
];

Im doing the tutorial on Angular website:

https://angular.io/start/start-routing

Im at the Routing part.

So i Assume that if the Params in the router for example the “id” does not exist in the products array, it will show undefined.

But would typescript not by default set a object that cannot be found to undefined or would it just crash?

what is the point of setting it at undefined anyways

OK, so Product is an interface, which is kind of like a “type”.

I would suggest looking at a crash course on Typescript video or something to get the basics down.

So i Assume that if the Params in the router for example the “id” does not exist in the products array, it will show undefined.

Yeah, I guess. I don’t know - I’ve never done Angular.

But would typescript not by default set a object that cannot be found to undefined or would it just crash?

TS will not do that unless you tell it to do it. And this:

product: Product | undefined;

warns TS that the value stored in the class member product could be undefined. In other words it is expecting the possibility of nothing there. And based on what we can see, that will be its starting value: undefined.

Will it crash? Not just because of that. Usually TS will give you some errors, telling you that the type of the variable you are trying to assign to that does not match type. Usually you’ll find that out before you run it. Could it crash? I doubt because of that, but if some other part of the code assumes that there is an object there, there might be a null pointer exception or something, but that has nothing to do with Angular or TS, that’s just JS.

what is the point of setting it at undefined anyways

Again, it’s not setting it as undefined. TS wants your variables typed - that’s kind of the point. This is common in most modern computer languages and some people think that is a weakness of JS - that’s why TS was invented.

It’s not setting it to undefined, it’s telling TS what types to expect. It’s either going to be type Products or it’s going to be undefined. That property is not initialized, so that means it will be undefined until it gets set to a value, presumably a value with type Product.

If you removed the “| undefined” I assume that it would throw an error because something of type Product cannot be undefined. That’s why it must be of type "Product | undefined". You might be able to get around that if you initialized it, like:

product: Product = INIT_PRODUCT;

and then manage it so it will always match type Product, but this is a valid approach as well.

It’s the union type of Product or explicitly undefined.

type T = Product | undefined;

That means it has to be one of those two. It doesn’t quite mean either of those two, it’s not discrete.

It means that unless you check what the value is before you try too use it, you may only use methods that are allowed for both. So you need to check if it’s not undefined before you can access T, which in this case is the value of product.

It’s afaics an error, because you’re saying that product cannot be missed out. If it’s not an object that matches Product, then it has to literally be undefined, the code should not compile otherwise.

undefined is normally used in JS to indicate a value that [natch] hasn’t been defined, it’s very rarely used explicitly (null is normally used for that). It should be like this afaics (unless the product API literally returns an object Product or undefined, which seems impossible if it’s something like JSON which has no concept of undefined):

product?: Product,

Which means “optionally Product”. This is similar, but means the object may or may not have the property product – you still need to check, but you don’t literally have product: undefined (which is I assume is never going to happen, but the code you posted says it is a possibility that must be accounted for)

2 Likes