Как динамически назначать свойство объекта в машинописном?

голоса
129

Если бы я хотел назначить программно свойство объекта в Javascript, я хотел бы сделать это следующим образом:

var obj = {};
obj.prop = value;

Но в машинописном, это приводит к ошибке:

Свойство «проп» не существует на значение типа «{}»

Как я должен назначить любое новое свойство объекта в машинописном?

Задан 03/10/2012 в 15:42
источник пользователем
На других языках...                            


21 ответов

голоса
111

Можно обозначить , objкак any, но побеждает всю цель использования машинописи. obj = {}подразумевает objэто Object. Маркировка как anyне имеет смысла. Для того, чтобы достичь желаемой консистенции интерфейс может быть определен следующим образом .

interface LooseObject {
    [key: string]: any
}

var obj: LooseObject = {};

ИЛИ сделать его компактным:

var obj: {[k: string]: any} = {};

LooseObjectможет принимать поля с любой строкой в качестве ключа и anyвведите в качестве значения.

obj.prop = "value";
obj.prop2 = 88;

Настоящая элегантность этого решения заключается в том, что вы можете включить типизированное поле в интерфейсе.

interface MyType {
    typesafeProp1?: number,
    requiredProp1: string,
    [key: string]: any
}

var obj: MyType ;
obj = { requiredProp1: "foo"}; // valid
obj = {} // error. 'requiredProp1' is missing
obj.typesafeProp1 = "bar" // error. typesafeProp1 should be a number

obj.prop = "value";
obj.prop2 = 88;
Ответил 08/06/2017 в 16:32
источник пользователем

голоса
61

Или все на одном дыхании:

  var obj:any = {}
  obj.prop = 5;
Ответил 03/10/2012 в 16:51
источник пользователем

голоса
45

Я , как правило , положить anyна другой стороне то есть var foo:IFoo = <any>{};Так что- то вроде этого еще типизированного:

interface IFoo{
    bar:string;
    baz:string;
    boo:string;     
}

// How I tend to intialize 
var foo:IFoo = <any>{};

foo.bar = "asdf";
foo.baz = "boo";
foo.boo = "boo";

// the following is an error, 
// so you haven't lost type safety
foo.bar = 123; 

В качестве альтернативы вы можете пометить эти свойства, как дополнительно:

interface IFoo{
    bar?:string;
    baz?:string;
    boo?:string;    
}

// Now your simple initialization works
var foo:IFoo = {};

Попробуйте онлайн

Ответил 26/08/2013 в 13:32
источник пользователем

голоса
24

Это решение полезно, когда ваш объект имеет определенный тип. Как при получении объекта к другому источнику.

let user: User = new User();
(user as any).otherProperty = 'hello';
//user did not lose its type here.
Ответил 25/08/2016 в 08:51
источник пользователем

голоса
21

Хотя компилятор жалуется, что все равно должны выводить его, как вам требуется. Тем не менее, это будет работать.

var s = {};
s['prop'] = true;
Ответил 03/10/2012 в 15:57
источник пользователем

голоса
14

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

var obj = {};
obj['prop'] = "value";

Ответил 22/03/2017 в 13:23
источник пользователем

голоса
4

Для того, чтобы гарантировать , что тип является Object(то есть пары ключ-значение ), используйте:

const obj: {[x: string]: any} = {}
obj.prop = 'cool beans'
Ответил 16/06/2017 в 14:15
источник пользователем

голоса
3

Лучше всего использовать безопасный ввод, я рекомендую вам:

interface customObject extends MyObject {
   newProp: string;
   newProp2: number;
}
Ответил 11/10/2016 в 23:32
источник пользователем

голоса
2
  • Случай 1:

    var car = {type: "BMW", model: "i8", color: "white"}; car['owner'] = "ibrahim"; // You can add a property:

  • Случай 2:

    var car:any = {type: "BMW", model: "i8", color: "white"}; car.owner = "ibrahim"; // You can set a property: use any type

Ответил 12/01/2019 в 15:45
источник пользователем

голоса
2

Для того, чтобы сохранить свой предыдущий тип, временный литой свой объект в любой

  var obj = {}
  (<any>obj).prop = 5;

Новая динамическая характеристика будет доступна только при использовании бросание:

  var a = obj.prop; ==> Will generate a compiler error
  var b = (<any>obj).prop; ==> Will assign 5 to b with no error;
Ответил 09/12/2016 в 16:44
источник пользователем

голоса
2

Храните любое новое свойство любого вида объекта, типажей его «любой»:

var extend = <any>myObject;
extend.NewProperty = anotherObject;

В дальнейшем вы можете извлечь его отливкой ваш расширенный объект обратно «любой»:

var extendedObject = <any>myObject;
var anotherObject = <AnotherObjectType>extendedObject.NewProperty;
Ответил 25/11/2015 в 13:21
источник пользователем

голоса
2

Вы можете добавить это заявление, чтобы заставить замолчать предупреждения.

declare var obj: any;

Ответил 03/10/2012 в 16:02
источник пользователем

голоса
1

Я удивлен, что ни один из ответов не ссылается Object.assign, поскольку это метод я использую, когда я думаю о «композиции» в JavaScript.

И это работает, как ожидалось в машинописном:

interface IExisting {
    userName: string
}

interface INewStuff {
    email: string
}

const existingObject: IExisting = {
    userName: "jsmith"
}

const objectWithAllProps: IExisting & INewStuff = Object.assign({}, existingObject, {
    email: "jsmith@someplace.com"
})

console.log(objectWithAllProps.email); // jsmith@someplace.com

преимущества

  • типобезопасность во всем, потому что вам не нужно использовать anyтип вообще
  • использует совокупный тип машинописи (как обозначаемые тем &при объявлении типа objectWithAllProps), в котором четко сообщается , что мы создание нового типа на лету (т.е. динамически)

Вещи, чтобы быть в курсе

  1. Object.assign имеет свои уникальные аспекты (которые хорошо известны большинству опытных разработчиков JS), которые следует учитывать при написании машинопись.
    • Он может быть использован в изменчивой моде, или непреложный образом (я демонстрирую неизменность путь выше, что означает , что existingObjectостается нетронутым , и , следовательно , не имеет emailсвойства. Для большинства программистов функционального стиля, это хорошо, так как результат только новые изменения).
    • Object.assign работает лучше всего, когда у вас есть плоские объекты. Если объединение двух вложенных объектов, содержащих NULLABLE свойства, вы можете закончить перезапись truthy значения с неопределенным. Если вы следите за порядком Object.assign аргументов, вы должны быть хорошо.
Ответил 30/01/2019 в 16:21
источник пользователем

голоса
1

Можно добавить элемент к существующему объекту,

  1. расширение типа (читай: расширить / специализировать интерфейс)
  2. литой исходный объект для расширенного типа
  3. добавить элемент к объекту
interface IEnhancedPromise<T> extends Promise<T> {
    sayHello(): void;
}

const p = Promise.resolve("Peter");

const enhancedPromise = p as IEnhancedPromise<string>;

enhancedPromise.sayHello = () => enhancedPromise.then(value => console.info("Hello " + value));

// eventually prints "Hello Peter"
enhancedPromise.sayHello();
Ответил 08/03/2018 в 11:20
источник пользователем

голоса
1

Если вы используете машинопись, предположительно вы хотите использовать типовую безопасность; в этом случае голый объект и «любой» являются противопоказано.

Лучше не использовать объект или {}, но некоторые с именем типа; или вы могли бы быть с помощью API с определенными типами, которые вам нужно расширить с помощью собственных полей. Я нашел, что это работа:

class Given { ... }  // API specified fields; or maybe it's just Object {}

interface PropAble extends Given {
    props?: string;  // you can cast any Given to this and set .props
    // '?' indicates that the field is optional
}
let g:Given = getTheGivenObject();
(g as PropAble).props = "value for my new field";

// to avoid constantly casting: 
let k:PropAble = getTheGivenObject();
k.props = "value for props";
Ответил 02/01/2018 в 03:07
источник пользователем

голоса
1

динамически назначать свойство объекта в машинописи.

Для этого вам просто нужно использовать машинопись интерфейсы следующим образом:

interface IValue {
    prop1: string;
    prop2: string;
}

interface IType {
    [code: string]: IValue;
}

Вы можете использовать его как то

var obj: IType = {};
obj['code1'] = { 
                 prop1: 'prop 1 value', 
                 prop2: 'prop 2 value' 
               };
Ответил 30/03/2017 в 04:31
источник пользователем

голоса
0

Вы можете использовать это:

this.model = Object.assign(this.model, { newProp: 0 });
Ответил 09/07/2019 в 23:53
источник пользователем

голоса
0

Вы можете создать новый объект на основе старого объекта с помощью оператора распространения

interface MyObject {
    prop1: string;
}

const myObj: MyObject = {
    prop1: 'foo',
}

const newObj = {
    ...myObj,
    prop2: 'bar',
}

console.log(newObj.prop2); // 'bar'

Машинопись будет выводить все поля исходного объекта и VSCode будет делать автодополнение и т.д.

Ответил 10/06/2019 в 01:59
источник пользователем

голоса
0

Простейшее будет следовать

const obj = <any>{};
obj.prop1 = "value";
obj.prop2 = "another value"
Ответил 02/05/2019 в 23:18
источник пользователем

голоса
0

Javascript:

myObj.myProperty = 1;

Машинопись:

myObj['myProperty'] = 1;
Ответил 09/02/2019 в 09:43
источник пользователем

голоса
-1

Если вы можете использовать функции ES6 JavaScript, вы можете использовать , вычисленные имена свойств , чтобы справиться с этим очень легко:

var req = {id : 0123456};    
var response = {responses: {[req.id]: 'The 0123456 response message'}};

[Req.id] Ключевой объект имеет динамическое значение

Ответил 16/01/2018 в 11:03
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more