¿Cómo puedo asignar dinámicamente las propiedades de un objeto a máquina de escribir?

votos
129

Si quería asignar mediante programación una propiedad de un objeto en Javascript, lo haría así:

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

Pero a máquina de escribir, esto genera un error:

La propiedad 'prop' no existe sobre el valor del tipo '{}'

¿Cómo se supone que voy a asignar cualquier nueva propiedad a un objeto a máquina de escribir?

Publicado el 03/10/2012 a las 15:42
fuente por usuario
En otros idiomas...                            


21 respuestas

votos
111

Es posible designar objcomo any, pero que en contra del propósito de la utilización de mecanografiado. obj = {}implica objes una Object. Marcándolo como anyno tiene sentido. Para lograr la consistencia deseada de una interfaz podría ser definido como sigue.

interface LooseObject {
    [key: string]: any
}

var obj: LooseObject = {};

O para que sea compacta:

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

LooseObjectpuede aceptar campos con cualquier cadena como clave y anyescribir como valor.

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

La elegancia real de esta solución es que se puede incluir typesafe campos en la interfaz.

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;
Respondida el 08/06/2017 a las 13:32
fuente por usuario

votos
61

O la totalidad de una sola vez:

  var obj:any = {}
  obj.prop = 5;
Respondida el 03/10/2012 a las 16:51
fuente por usuario

votos
45

Tiendo a poner anyen el otro lado es decir, var foo:IFoo = <any>{};así que algo como esto sigue siendo 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; 

Como alternativa, puede marcar estas propiedades como opcionales:

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

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

Pruébelo en línea

Respondida el 26/08/2013 a las 13:32
fuente por usuario

votos
24

Esta solución es útil cuando el objeto tiene tipo específico. Al igual que al obtener el objeto a otra fuente.

let user: User = new User();
(user as any).otherProperty = 'hello';
//user did not lose its type here.
Respondida el 25/08/2016 a las 05:51
fuente por usuario

votos
21

Aunque el compilador se queja de que aún debe de salida como usted requiere. Sin embargo, esto va a funcionar.

var s = {};
s['prop'] = true;
Respondida el 03/10/2012 a las 15:57
fuente por usuario

votos
14

Una opción más para hacer que se va a acceder a la propiedad como una colección:

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

Respondida el 22/03/2017 a las 10:23
fuente por usuario

votos
4

Para garantizar que el tipo es una Object(es decir, pares de valores clave ), utilice:

const obj: {[x: string]: any} = {}
obj.prop = 'cool beans'
Respondida el 16/06/2017 a las 11:15
fuente por usuario

votos
3

Lo más recomendable es utilizar la tipificación de seguridad, te recomiendo:

interface customObject extends MyObject {
   newProp: string;
   newProp2: number;
}
Respondida el 11/10/2016 a las 20:32
fuente por usuario

votos
2
  • Caso 1:

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

  • Caso 2:

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

Respondida el 12/01/2019 a las 15:45
fuente por usuario

votos
2

Para preservar su tipo anterior, el reparto temporal de su objeto a cualquier

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

La nueva propiedad dinámica sólo estará disponible cuando se utiliza el reparto:

  var a = obj.prop; ==> Will generate a compiler error
  var b = (<any>obj).prop; ==> Will assign 5 to b with no error;
Respondida el 09/12/2016 a las 13:44
fuente por usuario

votos
2

Almacenar cualquier nueva propiedad en cualquier tipo de objeto por typecasting a 'cualquier':

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

Más adelante se puede recuperar mediante la emisión de su objeto extendido de nuevo a 'cualquier':

var extendedObject = <any>myObject;
var anotherObject = <AnotherObjectType>extendedObject.NewProperty;
Respondida el 25/11/2015 a las 10:21
fuente por usuario

votos
2

Puede añadir esta declaración para silenciar las advertencias.

declare var obj: any;

Respondida el 03/10/2012 a las 16:02
fuente por usuario

votos
1

Me sorprende que ninguna de las respuestas de referencia Object.assign ya que es la técnica que utilizo cada vez que pienso "composición" en JavaScript.

Y funciona como se espera a máquina de escribir:

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

ventajas

  • seguridad de tipos a lo largo ya que no es necesario utilizar el anytipo del todo
  • utiliza el tipo de mecanografiado agregada (como se indica por el &al declarar el tipo de objectWithAllProps), que se comunica claramente que estamos componiendo un nuevo tipo en la marcha (es decir, de forma dinámica)

Cosas a tener en cuenta

  1. Object.assign tiene sus propios aspectos únicos (que son bien conocidos por la mayoría de los desarrolladores experimentados JS) que deben ser considerados cuando se escribe a máquina.
    • Se puede utilizar de una manera mutable, o de manera inmutable (I demuestran la forma inmutable anterior, lo que significa que existingObjectse mantiene intacto y por lo tanto no tiene una emailpropiedad. Para la mayoría de los programadores de estilo funcional, eso es una buena cosa ya que el resultado es el único nuevo cambio).
    • Object.assign funciona mejor cuando se tiene objetos planos. Si combina dos objetos anidados que contienen propiedades con valores nulos, que puede llegar a sobrescribir los valores Truthy con indefinido. Si usted tenga cuidado con el orden de los argumentos Object.assign, que debe estar bien.
Respondida el 30/01/2019 a las 16:21
fuente por usuario

votos
1

Es posible añadir un miembro a un objeto existente

  1. ampliando el tipo (es decir: de extensión / especializar la interfaz)
  2. convertir el objeto original al tipo extendido
  3. agregar el miembro al objeto
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();
Respondida el 08/03/2018 a las 08:20
fuente por usuario

votos
1

Si está utilizando Letra de imprenta, es de suponer que desea utilizar la seguridad de tipos; en cuyo caso objeto desnudo y 'cualquier' se contraindicado.

Mejor no usar objetos o {}, pero algún tipo llamado; o puede que esté utilizando una API con tipos específicos, que es necesario extender con sus propios campos. He encontrado que esto funcione:

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";
Respondida el 02/01/2018 a las 00:07
fuente por usuario

votos
1

dinámicamente asignar propiedades a un objeto a máquina de escribir.

Para hacer que usted sólo tiene que utilizar interfaces de mecanografiado de este modo:

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

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

se puede usar como esa

var obj: IType = {};
obj['code1'] = { 
                 prop1: 'prop 1 value', 
                 prop2: 'prop 2 value' 
               };
Respondida el 30/03/2017 a las 01:31
fuente por usuario

votos
0

se puede utilizar este:

this.model = Object.assign(this.model, { newProp: 0 });
Respondida el 09/07/2019 a las 23:53
fuente por usuario

votos
0

Puede crear nuevo objeto en función del objeto de edad utilizando el operador de difusión

interface MyObject {
    prop1: string;
}

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

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

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

Mecanografiado inferirá todos los campos del objeto original y VSCode hará terminación automática, etc.

Respondida el 10/06/2019 a las 01:59
fuente por usuario

votos
0

Más simple estará siguiendo

const obj = <any>{};
obj.prop1 = "value";
obj.prop2 = "another value"
Respondida el 02/05/2019 a las 23:18
fuente por usuario

votos
0

javascript:

myObj.myProperty = 1;

Mecanografiado:

myObj['myProperty'] = 1;
Respondida el 09/02/2019 a las 09:43
fuente por usuario

votos
-1

Si usted es capaz de utilizar las funciones de JavaScript ES6, puede utilizar Computarizada Nombres de propiedades para manejar esto muy fácilmente:

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

La clave de objeto [req.id] tiene un valor dinámico

Respondida el 16/01/2018 a las 08:03
fuente por usuario

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