Ryan Silva
Ryan Silva

Reputation: 965

Specifying the type of the value in an object literal in Typescript?

This is a different question than the one at Type definition in object literal in TypeScript

I have an interface that accepts any object as one of its properties:

interface MyType {
  /* ... */
  options: any;
}

While the property options can be anything, sometimes I want to specify certain types. I don't want to use the 'as' keyword because I don't want to coerce it (I want to see errors if I'm missing a property).

Here's one way I can do it:

interface MyTypeOptions {
  hasName: boolean;
  hasValue: boolean;
}

// Declare the options separately just so we can specify a type
const options: MyTypeOptions = {
  hasName: false,
  hasValue: true
};

const myType: MyType = {
  /* ... */
  options
}

But is there a way to do it while keeping the options inline inside the myType object literal, without using type assertion? In other words, I want to do this:

const myType: MyType = {
  /* ... */
  // I want to type-check that the following value is of type MyTypeOptions
  options: {
    hasName: false,
    hasValue: true
  } 
}

Upvotes: 3

Views: 342

Answers (2)

keysmusician
keysmusician

Reputation: 77

As of TypeScript 4.9 you can use the satisfies operator:

interface MyTypeOptions {
  hasName: boolean;
  hasValue: boolean;
}

const myType: MyType = {
  options: {
    hasName: false,
    hasValue: true
  } satisfies MyTypeOptions // Checks the type without casting it
}

Upvotes: 0

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249476

You are looking for generics. You can make MyType generic and specify MyTypeOptionsas a type parameter to MyType

interface MyTypeOptions {
    hasName: boolean;
    hasValue: boolean;
}

// Declare the options separately just so we can specify a type
const options: MyTypeOptions = {
    hasName: false,
    hasValue: true
}

// We specify any as the default to T so we can also use MyType without a type parameter
interface MyType<T = any> {
    /* ... */
    options: T;
}
const myType: MyType<MyTypeOptions> = {
    options: {
        hasName: false,
        hasValue: true
    }
}

Upvotes: 1

Related Questions