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

StackOverflow https://stackoverflow.com//questions/12710905

  •  13-12-2019
  •  | 
  •  

Вопрос

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

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

Но в TypeScript это генерирует ошибку:

Свойство «prop» не существует для значения типа «{}».

Как мне присвоить какое-либо новое свойство объекту в TypeScript?

Это было полезно?

Решение

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

interface LooseObject {
    [key: string]: any
}

var obj: LooseObject = {};
.

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

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

obj = {} может принимать поля с любой строкой в качестве ключа и типа obj в качестве значения.

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;
.

Другие советы

или все за один ход:

  var obj:any = {}
  obj.prop = 5;
.

Я склонен ставить 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 = {};

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

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

let user: User = new User();
(user as any).otherProperty = 'hello';
//user did not lose its type here.
.

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

var s = {};
s['prop'] = true;
.

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

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

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

interface MyObject {
    prop1: string;
}

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

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

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

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

Проще всего будет следовать

const obj = <any>{};
obj.prop1 = "value";
obj.prop2 = "another value"
.

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

const obj: {[x: string]: any} = {}
obj.prop = 'cool beans'

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

  1. Расширение типа (прочитайте: продлить / специализируйтесь на интерфейс)
  2. отбрасывает оригинальный объект к расширенному типу
  3. Добавить участника на объект
  4. 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();
    
    .

JavaScript:

myObj.myProperty = 1;
.

Типссы:

myObj['myProperty'] = 1;
.

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

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

Позже вы можете получить его, путем вытягивания расширенного объекта обратно на «любой»:

var extendedObject = <any>myObject;
var anotherObject = <AnotherObjectType>extendedObject.NewProperty;
.

    .
  • case 1:

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

  • case 2:

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

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

И это работает как ожидалось в Teadercript:

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 вообще
  • использует агрегатный тип типографии (как обозначается генеракодицетагкодом при объявлении типа &), который явно связывает, что мы составляем новый тип на лету (I.E. динамически)

<Сильные> вещи, которые нужно знать

  1. Object.Assign имеет свои уникальные аспекты (которые хорошо известны большинству опытных devs js), которые следует учитывать при написании Teadercript.
      .
    • его можно использовать в смежной моде или неизменному способу (я демонстрирую неизменяемый путь выше, что означает, что генеракодицетагкод остается нетронутым и, следовательно, не имеет свойства objectWithAllProps. Для большинства функциональных программистов стилей, это хорошо вещь, поскольку результат - единственное новое изменение).
    • Object.Assign работает лучше всего, когда у вас есть льденные объекты. Если вы объединяете два вложенных объекта, которые содержат ненужные свойства, вы можете в конечном итоге перезаписать правдивые значения с undefined. Если вы следите за порядком аргументов Object.assign, вы должны быть в порядке.

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

declare var obj: any;

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

interface customObject extends MyObject {
   newProp: string;
   newProp2: number;
}
.

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

this.model = Object.assign(this.model, { newProp: 0 });
.

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

  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;
.

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

Лучше не использовать объект или {}, но какой-то названный тип;Или вы можете использовать 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";
.

Динамически назначать свойства объекта в TypeScript.

Для этого вам просто нужно использовать интерфейсы TeampScript, которые так:

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

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

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

var obj: IType = {};
obj['code1'] = { 
    prop1: 'prop 1 value', 
    prop2: 'prop 2 value' 
};
.

Попробуйте:

export interface QueryParams {
    page?: number,
    limit?: number,
    name?: string,
    sort?: string,
    direction?: string
}
.

Тогда используйте его

const query = {
    name: 'abc'
}
query.page = 1
.

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top