1

I have a typescript interface that represent my data in database, like :

interface Foo {
  bar: {
    fish: {
       _id: string,
       name: string,
    }[],
  },

  starwars: string[],
}

I would like to be able to reference parts of this interface. In the following example, I want to pass the data behind the key fish as parameters.

I succedded to make it work doing :

interface Fish {
  _id: string,
  name: string,
}

interface Foo {
  bar: {
    fish: Fish[],
  },

  starwars: string[],
}

function killTheFish(fish: Fish) { ... }

But I would prefer doing something like :

type Fish = Foo.bar.fish;

Do you know any way to reference a part of an interface ?

2 Answers 2

4

Yes, you want lookup types, aka indexed access types. It uses the square bracket notation instead of dot notation (which would collide with namespaces):

type FishArray = Foo["bar"]["fish"]
/*
type FishArray = {
    _id: string;
    name: string;
}[]
*/

type Fish = Foo["bar"]["fish"][number];
/* type Fish = {
    _id: string;
    name: string;
} */

If you have a property-having type T and a keylike type K which is part of the keys of T (K extends keyof T), then T[K] is the type of the property of T at that key K. So Foo["bar"]["fish"] is the type you get if you have a foo object of type Foo and read foo.bar.fish.

That's an array in your example; if you want the element type, you can get that. Arrays have a numeric index signature, so if you have a key of type number, then you'll get the element type. So Foo["bar"]["fish"][number] is that element type.

Okay, hope that helps; good luck!

Playground link

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

1 Comment

Magnificent. Note that when there are arrays of same elements, example of syntax is : Foo['bar'][0]['obiwan'][0]['kenobi']
1

Without further ado - we can access mapped type member types by index/key using lookup type syntax ['prop']

type FishArr = Foo['bar']['fish'];

Array type is also mapped type Array<X> = {[k:number]: X}, so all keys have a type number, then by the same way we take a member type from any other mapped type, we can use number for array type element

type Fish = Foo['bar']['fish'][number];

Comments

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.