Defining typescript types using parenthesis and square brackets, what's their meaning? [closed]

Which role are playing the square brackets and the parenthesis when defining new types in Typescript? In the example below which should be the shape of the data for a variable with typeThree?

I played around with it and discovered the following so far.

type typeOne = { [id: string] : string; };
type typeTwo = { id : string; };
type typeThree = { (id: string) : string; };
let varOne: typeOne[] = [{id:'', id2:''}]; // OK
let varTwo: typeOne[] = [{idd:''}]; // OK
let varThree: typeTwo[] = [{idd:''}]; // error
let varFour: typeTwo[] = [{id:'', id2:''}]; // error
let varFive: typeTwo[] = [{idd:''}]; // error
let varSix: typeTwo[] = [{id:''}]; // OK
  • typeOne seems to describe an array of maps whose keys and values are strings
  • typeTwo seems to describe an array of maps {id: 'any string'} must only contain one key called id
  • typeThree I don't know what it is describing.
2

1 Answer

Although you are using the type keyword, the documentation on interfaces will apply to each of your examples. Both type and interface work in the same way, but you can't use a type for heritage.

Indexers

Allows a map with arbitrary string keys. In the example below the keys must be a string (numbers are also allowed so technically it is id: string | number although you aren't allowed to explicitly state that) and the value must be a string (and only a string).

// Defines an indexer
// The id(or key) must be a string, or number.
// The value must be a string.
type TypeOne = { [id: string]: string; };
const a: TypeOne = {};
a['key'] = 'value';
// Example type violation Type '3' is not assignable to type 'string'
a['key'] = 3;

Indexers are described in the interface section of the handbook.

Object

The second type in your question is an object structure. It requires an object to have the named property, with an appropriately typed value. When creating an instance of the type using a literal, you'll get assisted with unknown properties (which aren't allowed) which helps to catch mis-spellings.

type TypeTwo = { id: string; };
const a: TypeTwo = { id: 'value'
}
// Object literal must only specify known values
const b: TypeTwo = { id: 'value', nmae: 'value'
}
// Type 'number' is not assignable to type 'string'.
const c: TypeTwo = { id: 4
} 

Function

The third type in your question describes a function. Examples below, including the sometimes mysterious case of example b, which is valid even though it doesn't have an id parameter. The logic on that one is that if you ignore the parameter in the function body, why force it in the signature. Calling code may supply it, but you aren't using it anyway.

type TypeThree = (id: string) => string;
const a: TypeThree = (id: string) => { return id;
};
const b: TypeThree = () => { return 'value';
}
// Types of parameters 'id' and 'id' are incompatible.
const c: TypeThree = (id: number) => { return 'value';
}
// Type 'number' is not assignable to type 'string'.
const d: TypeThree = (id: string) => { return 5;
}

See function types in the handbook.

1

You Might Also Like