Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript interface with named property and arbitrarily-named index properties of different type [duplicate]

I would like to create an interface for an object that has a certain type for a specific named property and a different type for all other properties.

How would I write a definition for foo below?

let foo = {
   size: 3,
   a: 'foo',
   b: 'bar',
   c: 'baz'
}

This would be my intuitive approach:

interface Foo {
    size: number;
    [name: string]: string;
}

However, TypeScript tries to apply the general definition to the specific definition and triggers the following error:

error TS2411: Property 'size' of type 'number' is not assignable to string index type 'string'.
like image 924
lyschoening Avatar asked Jul 22 '15 11:07

lyschoening


People also ask

Can we have an interface with optional properties in TypeScript?

You must tell TypeScript if a property is optional. First, if you don't tell TypeScript that a property is optional, it will expect it to be set. Adding ? to the property name on a type, interface, or class definition will mark that property as optional.

How do you override interface properties TypeScript?

Use the Omit utility type to override the type of an interface property, e.g. interface SpecificLocation extends Omit<Location, 'address'> {address: newType} . The Omit utility type constructs a new type by removing the specified keys from the existing type.

What is the difference between type and interface in TypeScript?

// One major difference between type aliases vs interfaces are that interfaces are open and type aliases are closed. This means you can extend an interface by declaring it a second time. // In the other case a type cannot be changed outside of its declaration.

How do you create an interface for a dynamic object in TypeScript?

TypeScript allows you to specifically type an object using an interface that can be reused by multiple objects. To create an interface, use the interface keyword followed by the interface name and the typed object.


2 Answers

You can do something like this (I don't know if it will work in TS v1.5):

interface Size {
    size: number;
}

interface StringMap {
    [name: string]: string;
}

type Foo = Size & StringMap;
like image 65
franza Avatar answered Sep 17 '22 16:09

franza


Without defining every property, that's expected, but you can do this:

interface Foo1 {
    size: number;
    [name: string]: string|number;
}

Better than using any.

like image 28
thoughtrepo Avatar answered Sep 18 '22 16:09

thoughtrepo