Comment puis-je attribuer dynamiquement les propriétés à un objet dactylographiée?

voix
129

Si je voulais attribuer programatically une propriété à un objet en Javascript, je le ferais comme ceci:

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

Mais dactylographiée, cela génère une erreur:

La propriété « prop » n'existe pas sur la valeur de type « {} »

Comment suis-je censé affecter une nouvelle propriété à un objet dactylographiée?

Créé 03/10/2012 à 15:42
source utilisateur
Dans d'autres langues...                            


21 réponses

voix
111

Il est possible de désigner objcomme any, mais défaites tout le but de l' utilisation tapuscrit. obj = {}implique objest un Object. La marquer comme anyn'a aucun sens. Pour atteindre la consistance désirée une interface peut être définie comme suit.

interface LooseObject {
    [key: string]: any
}

var obj: LooseObject = {};

OU pour le rendre compact:

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

LooseObjectpeut accepter des champs avec une chaîne comme clé et anyentrez en tant que valeur.

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

L'élégance réelle de cette solution est que vous pouvez inclure Typesafe champs dans l'interface.

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;
Créé 08/06/2017 à 16:32
source utilisateur

voix
61

Ou en une seule fois:

  var obj:any = {}
  obj.prop = 5;
Créé 03/10/2012 à 16:51
source utilisateur

voix
45

J'ai tendance à mettre anyde l'autre côté -à- dire var foo:IFoo = <any>{};donc quelque chose comme ceci est encore 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; 

Sinon, vous pouvez marquer ces propriétés en option:

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

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

Essayez en ligne

Créé 26/08/2013 à 13:32
source utilisateur

voix
24

Cette solution est utile lorsque votre objet est de type spécifique. Comme lors de l'obtention de l'objet à une autre source.

let user: User = new User();
(user as any).otherProperty = 'hello';
//user did not lose its type here.
Créé 25/08/2016 à 08:51
source utilisateur

voix
21

Bien que le compilateur se plaint qu'il doit encore sortie comme vous avez besoin. Cependant, cela fonctionnera.

var s = {};
s['prop'] = true;
Créé 03/10/2012 à 15:57
source utilisateur

voix
14

Une option plus faire pour est d'accéder à la propriété en tant que collection:

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

Créé 22/03/2017 à 13:23
source utilisateur

voix
4

Pour garantir que le type est un Object( par exemple des paires clé-valeur ), utilisez:

const obj: {[x: string]: any} = {}
obj.prop = 'cool beans'
Créé 16/06/2017 à 14:15
source utilisateur

voix
3

La meilleure pratique est d'utiliser frappe sans danger, je vous recommande:

interface customObject extends MyObject {
   newProp: string;
   newProp2: number;
}
Créé 11/10/2016 à 23:32
source utilisateur

voix
2
  • Cas 1:

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

  • Cas n ° 2:

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

Créé 12/01/2019 à 15:45
source utilisateur

voix
2

Pour préserver votre type précédent, fonte temporaire de votre objet à tout

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

La nouvelle propriété dynamique ne sera disponible que lorsque vous utilisez la distribution:

  var a = obj.prop; ==> Will generate a compiler error
  var b = (<any>obj).prop; ==> Will assign 5 to b with no error;
Créé 09/12/2016 à 16:44
source utilisateur

voix
2

Conservez toute nouvelle propriété sur tout type d'objet par typecasting à « tout »:

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

Par la suite, vous pouvez le récupérer en lançant votre objet étendu de nouveau à « tout »:

var extendedObject = <any>myObject;
var anotherObject = <AnotherObjectType>extendedObject.NewProperty;
Créé 25/11/2015 à 13:21
source utilisateur

voix
2

Vous pouvez ajouter cette déclaration pour faire taire les avertissements.

declare var obj: any;

Créé 03/10/2012 à 16:02
source utilisateur

voix
1

Je suis surpris qu'aucune des réponses référence Object.assign puisque c'est la technique que je l'utilise chaque fois que je pense à la « composition » en JavaScript.

Et cela fonctionne comme prévu dactylographiée:

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

avantages

  • sécurité de type tout au long parce que vous n'avez pas besoin d'utiliser le anygenre du tout
  • utilise le type global de tapuscrit (comme indiqué par le &lors de la déclaration du type de objectWithAllProps), qui communique clairement que nous la composition sur la volée d' un nouveau type ( par exemple dynamique)

Les choses à connaître

  1. Object.assign a ses propres aspects uniques (qui sont bien connus pour la plupart des développeurs expérimentés JS) qui doivent être pris en compte lors de l'écriture tapuscrit.
    • Il peut être utilisé de façon mutable, ou d' une manière immuable (je montre la façon immuable ci - dessus, ce qui signifie que existingObjectreste intacte et ne dispose donc pas une emailpropriété. Pour la plupart des programmeurs de style fonctionnel, c'est une bonne chose car le résultat est le seul nouveau changement).
    • Object.assign fonctionne le mieux quand vous avez des objets plus plats. Si vous combinez deux objets imbriqués qui contiennent des propriétés nullables, vous pouvez finir par écraser les valeurs truthy avec indéfinie. Si vous faites attention à l'ordre des arguments Object.assign, vous devriez être bien.
Créé 30/01/2019 à 16:21
source utilisateur

voix
1

Il est possible d'ajouter un membre à un objet existant par

  1. l'élargissement du type (lire: étendre / spécialiser l'interface)
  2. jeter l'objet d'origine au type étendu
  3. ajouter le membre à l'objet
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();
Créé 08/03/2018 à 11:20
source utilisateur

voix
1

Si vous utilisez Tapuscrit, probablement que vous souhaitez utiliser la sécurité de type; auquel cas nu objet et « tout » sont contre-indiquée.

Mieux vaut ne pas utiliser l'objet ou {}, mais un certain type nommé; ou vous pourriez utiliser une API avec des types spécifiques, dont vous avez besoin avec vos propres étendre les champs. J'ai trouvé que cela fonctionne:

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";
Créé 02/01/2018 à 03:07
source utilisateur

voix
1

affecter dynamiquement les propriétés d'un objet dans la machine à écrire.

Pour ce faire vous avez juste besoin d'utiliser des interfaces dactylographiées comme ceci:

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

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

vous pouvez l'utiliser comme ça

var obj: IType = {};
obj['code1'] = { 
                 prop1: 'prop 1 value', 
                 prop2: 'prop 2 value' 
               };
Créé 30/03/2017 à 04:31
source utilisateur

voix
0

vous pouvez utiliser ceci:

this.model = Object.assign(this.model, { newProp: 0 });
Créé 09/07/2019 à 23:53
source utilisateur

voix
0

Vous pouvez créer un nouvel objet basé sur l'ancien objet en utilisant l'opérateur de diffusion

interface MyObject {
    prop1: string;
}

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

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

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

Tapuscrit inférera tous les champs de l'objet original et VSCode fera autocomplétion, etc.

Créé 10/06/2019 à 01:59
source utilisateur

voix
0

Simplest suivra

const obj = <any>{};
obj.prop1 = "value";
obj.prop2 = "another value"
Créé 02/05/2019 à 23:18
source utilisateur

voix
0

Javascript:

myObj.myProperty = 1;

Manuscrit:

myObj['myProperty'] = 1;
Créé 09/02/2019 à 09:43
source utilisateur

voix
-1

Si vous êtes en mesure d'utiliser les fonctionnalités ES6 JavaScript, vous pouvez utiliser Computed noms de propriété pour gérer très facilement:

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

La clé de l'objet [req.id] a une valeur dynamique

Créé 16/01/2018 à 11:03
source utilisateur

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