W jaki sposób dynamicznie przypisać właściwości do obiektu w maszynie?

głosy
129

Gdybym chciał programowo przypisać obiekt do obiektu w JavaScript, chciałbym zrobić to tak:

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

Ale w maszynopisie, to generuje błąd:

Własności „prop” nie istnieje na wartości typu „{}”

Jak mam przypisać każdą nową właściwość do obiektu w maszynie?

Utwórz 03/10/2012 o 15:42
źródło użytkownik
W innych językach...                            


21 odpowiedzi

głosy
111

Jest to możliwe do określenia objjak any, ale pokonuje cały cel korzystania maszynopis. obj = {}Oznacza objto Object. Oznaczając go jako anynie ma sensu. W celu uzyskania pożądanej konsystencji interfejs może być zdefiniowana w następujący sposób.

interface LooseObject {
    [key: string]: any
}

var obj: LooseObject = {};

OR, aby to kompaktowy:

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

LooseObjectMożna przyjąć pola z dowolnym ciągiem jako klucz i anywpisać jako wartość.

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

Prawdziwa elegancja tego rozwiązania jest to, że można dołączyć typesafe pola w interfejsie.

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;
Odpowiedział 08/06/2017 o 16:32
źródło użytkownik

głosy
61

Albo wszystko naraz:

  var obj:any = {}
  obj.prop = 5;
Odpowiedział 03/10/2012 o 16:51
źródło użytkownik

głosy
45

Staram się umieścić anypo drugiej stronie czyli var foo:IFoo = <any>{};Więc coś w tym jest jeszcze typesafe:

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; 

Alternatywnie można oznaczyć te właściwości jako opcja:

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

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

Spróbuj go online

Odpowiedział 26/08/2013 o 13:32
źródło użytkownik

głosy
24

To rozwiązanie jest przydatne, gdy obiekt ma określonego typu. Podobnie jak przy uzyskiwaniu obiekt do innego źródła.

let user: User = new User();
(user as any).otherProperty = 'hello';
//user did not lose its type here.
Odpowiedział 25/08/2016 o 08:51
źródło użytkownik

głosy
21

Mimo, że kompilator narzeka powinien nadal wyjście to jak wymagać. Jednak będzie to działać.

var s = {};
s['prop'] = true;
Odpowiedział 03/10/2012 o 15:57
źródło użytkownik

głosy
14

Jeszcze jedna opcja to zrobić, aby uzyskać dostęp do własności jako zbiór:

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

Odpowiedział 22/03/2017 o 13:23
źródło użytkownik

głosy
4

Aby zagwarantować, że typ jest Object(tzn par klucz-wartość ), należy:

const obj: {[x: string]: any} = {}
obj.prop = 'cool beans'
Odpowiedział 16/06/2017 o 14:15
źródło użytkownik

głosy
3

Najlepszą praktyką jest używać bezpiecznego pisania, polecam Ci:

interface customObject extends MyObject {
   newProp: string;
   newProp2: number;
}
Odpowiedział 11/10/2016 o 23:32
źródło użytkownik

głosy
2
  • Przypadek 1:

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

  • Przypadek 2:

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

Odpowiedział 12/01/2019 o 15:45
źródło użytkownik

głosy
2

Aby zachować swój poprzedni typ, tymczasowe oddać swój sprzeciw wobec każdego

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

Nowa właściwość dynamiczny będzie dostępny tylko w przypadku korzystania z obsady:

  var a = obj.prop; ==> Will generate a compiler error
  var b = (<any>obj).prop; ==> Will assign 5 to b with no error;
Odpowiedział 09/12/2016 o 16:44
źródło użytkownik

głosy
2

Przechowywać każdy nowy obiekt na wszelkiego rodzaju obiektu przez rzutowania go „any”:

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

Później można je odzyskać, oddając swój wydłużony przedmiot z powrotem do „każdy”:

var extendedObject = <any>myObject;
var anotherObject = <AnotherObjectType>extendedObject.NewProperty;
Odpowiedział 25/11/2015 o 13:21
źródło użytkownik

głosy
2

Możesz dodać tę deklarację, aby wyciszyć ostrzeżenia.

declare var obj: any;

Odpowiedział 03/10/2012 o 16:02
źródło użytkownik

głosy
1

Dziwię się, że żadna z odpowiedzi odwoływać Object.assign ponieważ to technika używam ilekroć myślę o „kompozycja” w JavaScript.

I działa zgodnie z oczekiwaniami w maszynopisie:

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

Zalety

  • Typ bezpieczeństwa całej bo nie trzeba używać anytypu w ogóle
  • wykorzystuje typ maszynopis za łączną (jak oznaczona &podczas deklarowania typ objectWithAllProps), który jasno komunikuje, że jesteśmy komponowania nowego typu on-the-fly (tj dynamicznie)

Rzeczy, aby zdawać sobie sprawę z

  1. Object.assign ma własne unikalne aspekty (które są dobrze znane większości doświadczonych deweloperów JS), które powinny być brane pod uwagę podczas pisania maszynopis.
    • Może być stosowany w zmienny sposób, albo niezmienny sposób (I zademonstrować sposób niezmienny powyżej, co oznacza, że existingObjectpozostaje nietknięty, a zatem nie mają emailwłasności. Dla większości programistów funkcjonalnym stylu, że to dobra rzecz, ponieważ wynik jest jedynym nowym zmiany).
    • Object.assign działa najlepiej, gdy masz bardziej płaskich przedmiotów. Jeśli połączenie dwóch zagnieżdżonych obiektów, które zawierają właściwości zerowalne, może skończyć się nadpisywania wartości truthy z niezdefiniowane. Jeśli zwrócić uwagę na kolejność Object.assign argumentów, powinno być w porządku.
Odpowiedział 30/01/2019 o 16:21
źródło użytkownik

głosy
1

Jest możliwe, aby dodać element do istniejącego obiektu przez

  1. poszerzenie typ (czytaj: extend / specjalizują interfejs)
  2. cast oryginalnego obiektu do rozszerzonego typu
  3. dodać element do obiektu
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();
Odpowiedział 08/03/2018 o 11:20
źródło użytkownik

głosy
1

Jeśli używasz maszynopis, prawdopodobnie chcesz użyć typu bezpieczeństwa; w takim przypadku nagi Przedmiot i „każdy” są counterindicated.

Lepiej nie używać przedmiot lub {}, ale niektóre nazwie typu; lub może być za pomocą interfejsu API z określonych typów, które trzeba rozszerzyć z własnych pól. Znalazłem to do pracy:

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";
Odpowiedział 02/01/2018 o 03:07
źródło użytkownik

głosy
1

dynamicznie przypisać właściwości do obiektu w maszynopisie.

Aby to zrobić wystarczy użyć interfejsów maszynopisu tak:

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

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

można go używać tak

var obj: IType = {};
obj['code1'] = { 
                 prop1: 'prop 1 value', 
                 prop2: 'prop 2 value' 
               };
Odpowiedział 30/03/2017 o 04:31
źródło użytkownik

głosy
0

można użyć to:

this.model = Object.assign(this.model, { newProp: 0 });
Odpowiedział 09/07/2019 o 23:53
źródło użytkownik

głosy
0

Można utworzyć nowy obiekt na podstawie starego obiektu przy użyciu operatora spread

interface MyObject {
    prop1: string;
}

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

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

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

Maszynopis będzie wnioskować wszystkie pola oryginalnego obiektu i VSCode zrobi autouzupełnianie, etc.

Odpowiedział 10/06/2019 o 01:59
źródło użytkownik

głosy
0

Najprostszym będą następujące

const obj = <any>{};
obj.prop1 = "value";
obj.prop2 = "another value"
Odpowiedział 02/05/2019 o 23:18
źródło użytkownik

głosy
0

javascript:

myObj.myProperty = 1;

Maszynopis:

myObj['myProperty'] = 1;
Odpowiedział 09/02/2019 o 09:43
źródło użytkownik

głosy
-1

Jeśli jesteś w stanie wykorzystać możliwości ES6 JavaScript, można użyć obliczone nazwy właściwości obsłużyć to bardzo prosty sposób:

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

Przycisk [req.id] klucz obiekt ma wartość dynamiczną

Odpowiedział 16/01/2018 o 11:03
źródło użytkownik

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