operator nodejs example español ejemplos typescript

typescript - nodejs - Valores predeterminados de la interfaz de mecanografía



typescript version (6)

¿Puedo decirle a la interfaz que predetermina las propiedades que no proporciono a nulo? ¿Qué me dejaría hacer esto?

No. Pero, por defecto, no están undefined que en general está bien. Puede usar el siguiente patrón, es decir, tener una aserción de tipo en el punto de creación:

let x: IX = {} as any; x.a = ''xyz'' x.b = 123 x.c = new AnotherType()

Tengo este y otros patrones documentados aquí: basarat.gitbooks.io/typescript/content/docs/tips/…

Tengo la siguiente interfaz en TypeScript:

interface IX { a: string, b: any, c: AnotherType }

Declaro una variable de ese tipo e inicializo todas las propiedades

let x: IX = { a: ''abc'', b: null, c: null }

Luego les asigno valores reales en una función init más tarde

x.a = ''xyz'' x.b = 123 x.c = new AnotherType()

Pero no me gusta tener que especificar un grupo de valores nulos predeterminados para cada propiedad al declarar el objeto cuando se establecerán más tarde en valores reales. ¿Puedo decirle a la interfaz que predetermina las propiedades que no proporciono a nulo? ¿Qué me dejaría hacer esto?

let x: IX = { a: ''abc'' }

sin obtener un error del compilador. Ahora me dice

TS2322: El tipo ''{}'' no es asignable al tipo ''IX''. Falta la propiedad ''b'' en el tipo ''{}''.


Me topé con esto mientras buscaba una forma mejor de lo que había llegado. Después de leer las respuestas y probarlas, pensé que valía la pena publicar lo que estaba haciendo, ya que las otras respuestas no me parecieron tan breves. Para mí era importante tener que escribir una pequeña cantidad de código cada vez que configuraba una nueva interfaz. Me decidí por ...

Utilizando una función genérica personalizada de deepCopy:

deepCopy = <T extends {}>(input: any): T => { return JSON.parse(JSON.stringify(input)); };

Define tu interfaz

interface IX { a: string; b: any; c: AnotherType; }

... y define los valores predeterminados en una const separada.

const XDef : IX = { a: '''', b: null, c: null, };

Entonces inicie así:

let x : IX = deepCopy(XDef);

Eso es todo lo que se necesita ...

.. sin embargo ..

Si desea inicializar cualquier elemento raíz , puede modificar la función deepCopy para aceptar valores predeterminados personalizados. La función se convierte en:

deepCopyAssign = <T extends {}>(input: any, rootOverwrites?: any): T => { return JSON.parse(JSON.stringify({ ...input, ...rootOverwrites })); };

Que luego se puede llamar así:

let x : IX = deepCopyAssign(XDef, { a:''customInitValue'' } );

Cualquier otra forma preferida de copia profunda funcionaría. Si solo se necesita una copia superficial, Object.assign sería suficiente, dejando de lado la necesidad de la función deepCopy o deepCopyAssign .

let x : IX = object.assign({}, XDef, { a:''customInitValue'' });

Problemas conocidos

  • No se asignará en profundidad de esta manera, pero no es demasiado difícil modificar deepCopyAssign para iterar y verificar los tipos antes de asignar.
  • El proceso de análisis / stringify perderá funciones y referencias. No los necesito para mi tarea y tampoco el OP.
  • Los valores de inicio personalizados no son insinuados por el IDE o el tipo verificado cuando se ejecuta.

No puede establecer valores predeterminados en una interfaz, pero puede lograr lo que desea hacer utilizando Propiedades opcionales (compare el párrafo 3):

https://www.typescriptlang.org/docs/handbook/interfaces.html

Simplemente cambie la interfaz a:

interface IX { a: string, b?: any, c?: AnotherType }

Entonces puedes hacer:

let x: IX = { a: ''abc'' }

Y use su función init para asignar valores predeterminados a xb y xc si esas propiedades no están establecidas.


Puede implementar la interfaz con una clase, luego puede tratar de inicializar los miembros en el constructor:

class IXClass implements IX { a: string; b: any; c: AnotherType; constructor(obj: IX); constructor(a: string, b: any, c: AnotherType); constructor() { if (arguments.length == 1) { this.a = arguments[0].a; this.b = arguments[0].b; this.c = arguments[0].c; } else { this.a = arguments[0]; this.b = arguments[1]; this.c = arguments[2]; } } }

Otro enfoque es usar una función de fábrica:

function ixFactory(a: string, b: any, c: AnotherType): IX { return { a: a, b: b, c: c } }

Entonces puedes simplemente:

var ix: IX = null; ... ix = new IXClass(...); // or ix = ixFactory(...);



Si bien la respuesta de @ Timar funciona perfectamente para los valores predeterminados null (lo que se solicitó), aquí hay otra solución fácil que permite otros valores predeterminados: definir una interfaz de opción, así como una constante correspondiente que contenga los valores predeterminados; en el constructor use el operador de propagación para establecer la variable miembro de options

interface IXOptions { a?: string, b?: any, c?: number } const XDefaults: IXOptions = { a: "default", b: null, c: 1 } export class ClassX { private options: IXOptions; constructor(XOptions: IXOptions) { this.options = { ...XDefaults, ...XOptions }; } public printOptions(): void { console.log(this.options.a); console.log(this.options.b); console.log(this.options.c); } }

Ahora puedes usar la clase así:

const x = new ClassX({ a: "set" }); x.printOptions();

Salida:

set null 1