Определение типа в объектном литерале в TypeScript

В классах TypeScript можно объявлять типы для свойств, например:

class className {
  property: string;
};

Как объявить тип свойства в литерале объекта?

Я пробовал следующий код, но он не компилируется:

var obj = {
  property: string;
};

Я получаю следующую ошибку:

Имя 'строка' не существует в текущей области

Я что-то не так делаю или это ошибка?

Ответ 1

Вы довольно близки, вам просто нужно заменить = на :. Вы можете использовать литерал типа объекта (см. Раздел спецификации 3.5.3) или интерфейс. Использование литерала типа объекта близко к тому, что у вас есть:

var obj: { property: string; } = { property: "foo" };

Но вы также можете использовать интерфейс

interface MyObjLayout {
    property: string;
}

var obj: MyObjLayout = { property: "foo" };

Ответ 2

Используйте оператор приведения, чтобы сделать это кратким (приведя значение null к нужному типу).

var obj = {
    property: <string> null
};

Более длинный пример:

var call = {
    hasStarted: <boolean> null,
    hasFinished: <boolean> null,
    id: <number> null,
};

Это гораздо лучше, чем две части (одна для объявления типов, вторая для объявления значений по умолчанию):

var callVerbose: {
    hasStarted: boolean;
    hasFinished: boolean;
    id: number;
} = {
    hasStarted: null,
    hasFinished: null,
    id: null,
};

Обновление 2016-02-10 - для обработки TSX (спасибо @Джош)

Используйте оператор as для TSX.

var obj = {
    property: null as string
};

Более длинный пример:

var call = {
    hasStarted: null as boolean,
    hasFinished: null as boolean,
    id: null as number,
};

Обновление 2019-05-15 (улучшенный шаблон кода в качестве альтернативы)

После многих лет использования const и использования более функционального кода я рекомендовал бы в большинстве случаев не использовать вышеуказанное. (Вышеприведенное создает изменяемый объект, в котором поле будет установлено во всей функции вместо всех сразу - что приводит к ошибкам несогласованного состояния).

Вместо этого я бы рекомендовал максимально использовать const переменные, а затем создать объект в качестве последнего шага:

const id = GetId();
const hasStarted = true;
...
const hasFinished = false;
...
return {hasStarted, hasFinished, id};
  • Это будет правильно печатать все без необходимости явной печати.
  • Нет необходимости перепечатывать имена полей.
  • Это приводит к чистому коду из моего опыта.
  • Это позволяет компилятору обеспечить больше проверки состояния (например, если вы вернетесь в нескольких местах, компилятор будет гарантировать, что всегда возвращается один и тот же тип объекта - что побуждает вас объявлять все возвращаемое значение в каждой позиции - давая совершенно ясную информацию). намерение этой ценности).

Ответ 3

Если вы пытаетесь написать аннотацию типа, синтаксис следующий:

var x: { property: string; } = ...;

Если вы пытаетесь написать литерал объекта, синтаксис следующий:

var x = { property: 'hello' };

Ваш код пытается использовать имя типа в позиции значения.

Ответ 4

В TypeScript, если мы объявляем объект, мы бы использовали следующий синтаксис:

[access modifier] variable name : { /* structure of object */ }

Например:

private Object:{ Key1: string, Key2: number }

Ответ 5

Я удивлен, что никто не упомянул об этом, но вы могли бы просто создать интерфейс с именем ObjectLiteral, который принимает пары key: value типа string: any:

interface ObjectLiteral {
  [key: string]: any;
}

Тогда вы бы использовали его, вот так:

let data: ObjectLiteral = {
  hello: "world",
  goodbye: 1,
  // ...
};

Дополнительным бонусом является то, что вы можете повторно использовать этот интерфейс столько раз, сколько вам нужно, на любом количестве объектов.

Удачи.

Ответ 6

Если вы пытаетесь добавить типизацию к литералу деструктурированного объекта, например, в аргументах функции, синтаксис:

function foo({ bar, baz }: { bar: boolean, baz: string }) {
  // ...
}

foo({ bar: true, baz: 'lorem ipsum' });

Ответ 7

В вашем коде:

var obj = {
  myProp: string;
};

Вы фактически создаете литерал объекта и присваиваете строку переменной свойству myProp. Хотя это очень плохая практика, на самом деле это будет действительный код TS (не используйте его!):

var string = 'A string';

var obj = {
  property: string
};

Однако вы хотите, чтобы литерал объекта был напечатан. Это может быть достигнуто различными способами:

Интерфейс:

interface myObj {
    property: string;
}

var obj: myObj = { property: "My string" };

Пользовательский тип:

type myObjType = {
    property: string
};

var obj: myObjType = { property: "My string" };

Оператор приведения:

var obj = {
    myString: <string> 'hi',
    myNumber: <number> 132,
};

Литерал типа объекта:

var obj: { property: string; } = { property: "Mystring" };

Ответ 8

// Use ..

const Per = {
  name: 'HAMZA',
  age: 20,
  coords: {
    tele: '09',
    lan: '190'
  },
  setAge(age: Number): void {
    this.age = age;
  },
  getAge(): Number {
    return age;
  }
};
const { age, name }: { age: Number; name: String } = Per;
const {
  coords: { tele, lan }
}: { coords: { tele: String; lan: String } } = Per;

console.log(Per.getAge());

Ответ 9

Вы можете объявить объект и назначить ключи и значения следующим образом:

   let input={};

   input["key1"] = value1;
   input["key2"] = value2;

Теперь гибко добавлять ключ и значение в любое время для этого объекта в зависимости от вашей логики:

    if(flag){
    input["key3"] = value3;
    }