Diego  Elizondo

Diego Elizondo

1657120860

Comprender El Signo De Exclamación En TypeScript

El signo de exclamación !se conoce como el operador de aserción no nulo en TypeScript. Usaremos estos términos indistintamente en este artículo. Pero, ¿qué hace este operador?

¿Qué es el signo de exclamación de TypeScript?

El operador de aserción no nulo le dice al compilador de TypeScript que un valor escrito como opcional no puede ser nullo undefined. Por ejemplo, si definimos una variable como posiblemente una cadena o indefinida, el !operador le dice al compilador que ignore la posibilidad de que no esté definida.

Qué hace el signo de exclamación en TypeScript

Digamos que una variable se define como posiblemente nula o indefinida, así:

let x: string | undefined 

O, digamos que una función se define para aceptar un argumento opcional, así:

function printString (str ?: string) { … }

En estos casos, si intentamos hacer referencia a esa variable como un tipo definido, entonces el compilador de TypeScript nos daría un mensaje de error, como el siguiente:

Object is possibly 'undefined'. ts(2532)

Podemos usar el operador de aserción no nulo para decirle al compilador explícitamente que esta variable tiene un valor y no es nullo undefined. Revisemos algunos ejemplos para comprender mejor el signo de exclamación en TypeScript.

Ejemplo 1: Uso de una variable de tipo string | nullpara una función que aceptastring

Digamos que definimos una variable wordcon el tipo como string | null. Esto significa que a lo largo de nuestro código, wordpuede contener un stringvalor o un nullvalor.

Si intentamos usar una función solo disponible para stringtipos en word, TypeScript la rechazará porque existe una posibilidad en nuestro código que wordcontiene un nulltipo de valor:

let word : string | null = null
const num = 1
if (num) {
    word = "Hello World!"    
}
console.log(word.toLowerCase()) // Error: Object is possibly 'null'.ts(2531)

Usando el !operador de aserción no nulo, podemos decirle a TypeScript que estamos seguros de wordque nunca lo será null(o undefined), por lo que puede aplicarle con confianza funciones de cadena:

 

let word : string | null = null
const num = 1
if (num) {
    word = "Hello World!"    
}
console.log(word!.toLowerCase())

Con esta pequeña adición, el compilador ya no cree que exista la posibilidad de que wordsea nulo.

Ejemplo 2: Asignar el valor de un argumento opcional a una variable dentro de una función

En otro ejemplo, digamos que creamos una función printNameque acepta un argumento opcional personName.

Tenga en cuenta que definir un argumento de función como uso opcional ?:es lo mismo que definir el tipo como posiblemente indefinido. Por ejemplo, arg?: stringes lo mismo que arg: string | undefined.

Si intentamos reasignar ese argumento opcional personNamea otra variable de tipo string, ocurriría lo siguiente:

function printName(personName?: string) {
    const fullName: string = personName 
/** 
 * Error: Type 'string | undefined' is not assignable to type 'string'. 
 * Type 'undefined' is not assignable to type 'string'.
 */
    console.log(`The name is ${fullName}`)
}

Podemos arreglar los errores de TypeScript arrojados en nuestro fragmento anterior usando el !operador:

function printName(personName?: string) {
    const fullName: string = personName! 
    console.log(`The name is ${fullName}`)
}

Ahora, el compilador entiende que personName no puede ser nulo o indefinido, lo que lo hace asignable a type string.

Ejemplo 3: Imprimir el atributo de un argumento de objeto opcional dentro de una función

En nuestro ejemplo final, definiremos un tipo Persony una función printNameque acepta un argumento opcional de tipo Person. Veamos qué sucede si intentamos utilizar printNamepara imprimir el atributo de nombre de Person:

interface Person {
    name: string
    age: number
}

function printName(person?: Person) {
    console.log(`The name is ${person.name}`) // Error: Object is possibly 'undefined'. ts(2532)
}

Arreglemos este error de TypeScript usando nuestro !operador:

interface Person {
    name: string
    age: number
}

function printName(person?: Person) {
    console.log(`The name is ${person!.name}`)
}

Tenga en cuenta que TypeScript tiene una alternativa para hacer referencia a atributos y funciones en objetos que pueden ser nulos o indefinidos, llamada operador de encadenamiento opcional ?.. Por ejemplo, person?.nameo word?.toString()regresará undefinedsi la variable no está definida o es nula.

Sin embargo, el operador de encadenamiento opcional ?.no puede resolver los errores de TypeScript en nuestro segundo ejemplo, en el que tratamos de asignar el valor de un tipo de variable string | undefineda un tipo de variable string. Obtenga más información sobre el encadenamiento opcional en la última sección de este artículo .

Casos de uso populares para el signo de exclamación de TypeScript

Como hemos visto en nuestros ejemplos, el !operador es muy útil cuando deseamos que TypeScript trate nuestra variable como un tipo sólido. Esto evita que tengamos que manejar casos nulos o indefinidos cuando estamos seguros de que no existe tal caso.

Ahora que hemos visto algunos ejemplos para comprender mejor el signo de exclamación de TypeScript, veamos algunos casos de uso populares para este operador.

Realizar búsquedas en una matriz

Imaginemos que tenemos una matriz de objetos y queremos elegir un objeto con un valor de atributo particular, así:

interface Person {
    name: string
    age: number
    sex: string
}

const people: Person[] = [
  {
      name: 'Gran',
      age: 70,
      sex: 'female'
  },
  {
      name: 'Papa',
      age: 72,
      sex: 'male'
  },
  {
      name: 'Mom',
      age: 35,
      sex: 'female'
  },
  {
      name: 'Dad',
      age: 38,
      sex: 'male'
  }
]

const femalePerson = people.find(p => p.sex === 'female')

En nuestro fragmento anterior, TypeScript definirá el tipo de femalePersoncomo Person | undefinedporque es posible que people.findno produzca ningún resultado, en otras palabras, que no estará definido.

Sin embargo, si femalePersontiene el tipo Person | undefined, no podremos pasarlo como argumento a una función que espera el tipo Person.

Cuando realizamos búsquedas en estas matrices, a menudo confiamos en que tienen valores definidos y, por lo tanto, no creemos que exista ningún caso indefinido. Nuestro !operador puede salvarnos del manejo adicional, o innecesario, de casos nulos o indefinidos.

Agregue el operador de aserción no nulo, así:

const femalePerson = people.find(p => p.sex === 'female')!

Esto haría femalePersontener el tipo Person.

React refs y manejo de eventos

Las referencias de React se utilizan para acceder a los nodos HTML DOM renderizados o a los elementos de React. Las referencias se crean usando React.createRef<HTMLDivElement>()y luego se adjuntan al elemento usando el refatributo.

Para usar React refs, accedemos al atributo actual, ref.current. Hasta que el elemento se represente, ref.currentpodría ser null, por lo que tiene el siguiente tipo:

HTMLDivElement | null

Para adjuntar un evento a ref.current, primero tendríamos que manejar los nullvalores posibles. Aquí hay un ejemplo:

import React from 'react'

const ToggleDisplay = () => {
    const displayRef = React.createRef<HTMLDivElement>()

    const toggleDisplay = () => {
        if (displayRef.current) {
            displayRef.current.toggleAttribute('hidden')
        }
    }

    return (
        <div>
            <div class="display-panel" ref="displayRef">
                <p> some content </p>
            </div>
            <button onClick={toggleDisplay}>Toggle Content</button>
        <div>
    )
}

En el fragmento anterior, tuvimos que manejar una verificación de tipo para displayRef.currentusar una ifdeclaración antes de llamar a la toggleAttributefunción.

En la mayoría de los casos, estamos seguros de que si onClickse activa el evento del botón, nuestros elementos ya están representados. Por lo tanto, no hay necesidad de un control. Esta verificación innecesaria se puede eliminar usando el !operador, así:

const displayRef = React.createRef<HTMLDivElement>()

const toggleDisplay = () => displayRef.current!.toggleAttribute('hidden')

return (
        <div>
        ...

La desventaja de usar el signo de exclamación en TypeScript

El !operador no cambia el comportamiento de tiempo de ejecución de su código. Si el valor que ha afirmado no es nullo undefinedresulta ser nullo undefined, se producirá un error e interrumpirá la ejecución de su código.

Recuerde, la diferencia entre TypeScript y JavaScript es la aserción de tipos. En JavaScript no necesitamos ni usamos el !operador porque no hay tipo estricto.

Se puede crear una instancia de una variable de JavaScript stringy cambiarla a object, nullo numberdurante la ejecución del código. Esto deja en manos del desarrollador el manejo de los diferentes casos.

El uso del !operador elimina el "superpoder" de TypeScript de evitar errores de tipo en tiempo de ejecución. Por lo tanto, no es la mejor práctica usar el !operador.

Alternativas al uso del signo de exclamación de TypeScript

Puede usar encadenamientos opcionales o predicados de tipos como alternativas a las aserciones no nulas.

El encadenamiento opcional es una forma abreviada de TypeScript que nos permite manejar fácilmente los casos en los que la variable está definida o no. Cuando la variable no está definida o es nula, el valor al que se hace referencia por defecto es value undefined. He aquí un ejemplo de encadenamiento opcional:

interface Person {
    name: string
    age: number
    sex: string
}

function printName(person?: Person): void {
    console.log('The name of this person is', person?.name)
}

En nuestro ejemplo anterior, si personno está definido, nuestra salida de impresión sería la siguiente:

'The name of this person is undefined'

El uso de predicados de tipo en TypeScript se realiza definiendo una función que realiza una prueba booleana y devuelve un predicado de tipo en el formulario arg is Type. Aquí hay un ejemplo:

interface Person {
    name: string
    age: number
    sex: string
}

function validatePerson(person?: Person) person is Person {
    return !!person
}

Usando este tipo de predicado, primero podemos validar el objeto antes de realizar más operaciones, así:

function printName(person?: Person) {
    if (!validatePerson(person)) {
        console.log('Person is invalid')
        return
    }

    console.log(`The name is ${person.name}`)
}

Conclusión

El poder de TypeScript sobre JavaScript es la seguridad de tipos que proporciona a nuestro código . Sin embargo, es posible que a veces queramos deshabilitar las comprobaciones estrictas de tipos de TypeScript, por ejemplo, en aras de la flexibilidad o la compatibilidad con versiones anteriores. En tales casos, podemos usar el operador de aserción no nulo.

Si bien es una característica útil, lo animo a explorar métodos de aserción de tipos más seguros. Puede ir un paso más allá para evitar el uso de esta operación en su proyecto y con su equipo agregando el typescript-eslintpaquete a su proyecto y aplicando la no-non-null-assertionregla de lint .

Fuente: https://blog.logrocket.com/understanding-exclamation-mark-typescript/

#typescript 

What is GEEK

Buddha Community

Comprender El Signo De Exclamación En TypeScript

The Definitive Guide to TypeScript & Possibly The Best TypeScript Book

TypeScript Deep Dive

I've been looking at the issues that turn up commonly when people start using TypeScript. This is based on the lessons from Stack Overflow / DefinitelyTyped and general engagement with the TypeScript community. You can follow for updates and don't forget to ★ on GitHub 🌹

Reviews

  • Thanks for the wonderful book. Learned a lot from it. (link)
  • Its probably the Best TypeScript book out there. Good Job (link)
  • Love how precise and clear the examples and explanations are! (link)
  • For the low, low price of free, you get pages of pure awesomeness. Chock full of source code examples and clear, concise explanations, TypeScript Deep Dive will help you learn TypeScript development. (link)
  • Just a big thank you! Best TypeScript 2 detailed explanation! (link)
  • This gitbook got my project going pronto. Fluent easy read 5 stars. (link)
  • I recommend the online #typescript book by @basarat you'll love it.(link)
  • I've always found this by @basarat really helpful. (link)
  • We must highlight TypeScript Deep Dive, an open source book.(link)
  • Great online resource for learning. (link)
  • Thank you for putting this book together, and for all your hard work within the TypeScript community. (link)
  • TypeScript Deep Dive is one of the best technical texts I've read in a while. (link)
  • Thanks @basarat for the TypeScript Deep Dive Book. Help me a lot with my first TypeScript project. (link)
  • Thanks to @basarat for this great #typescript learning resource. (link)
  • Guyz excellent book on Typescript(@typescriptlang) by @basarat (link)
  • Leaning on the legendary @basarat's "TypeScript Deep Dive" book heavily at the moment (link)
  • numTimesPointedPeopleToBasaratsTypeScriptBook++; (link)
  • A book not only for typescript, a good one for deeper JavaScript knowledge as well. link
  • In my new job, we're using @typescriptlang, which I am new to. This is insanely helpful huge thanks, @basarat! link
  • Thank you for writing TypeScript Deep Dive. I have learned so much. link
  • Loving @basarat's @typescriptlang online book basarat.gitbooks.io/typescript/# loaded with great recipes! link
  • Microsoft doc is great already, but if want to "dig deeper" into TypeScript I find this book of great value link
  • Thanks, this is a great book 🤓🤓 link
  • Deep dive to typescript is awesome in so many levels. i find it very insightful. Thanks link
  • @basarat's intro to @typescriptlang is still one of the best going (if not THE best) link
  •  
  • This is sweet! So many #typescript goodies! link

Get Started

If you are here to read the book online get started.

Translations

Book is completely free so you can copy paste whatever you want without requiring permission. If you have a translation you want me to link here. Send a PR.

Other Options

You can also download one of the Epub, Mobi, or PDF formats from the actions tab by clicking on the latest build run. You will find the files in the artifacts section.

Special Thanks

All the amazing contributors 🌹

Share

Share URL: https://basarat.gitbook.io/typescript/

Author: Basarat
Source Code: https://github.com/basarat/typescript-book/ 
License: View license

#typescript #opensource 

Diego  Elizondo

Diego Elizondo

1657120860

Comprender El Signo De Exclamación En TypeScript

El signo de exclamación !se conoce como el operador de aserción no nulo en TypeScript. Usaremos estos términos indistintamente en este artículo. Pero, ¿qué hace este operador?

¿Qué es el signo de exclamación de TypeScript?

El operador de aserción no nulo le dice al compilador de TypeScript que un valor escrito como opcional no puede ser nullo undefined. Por ejemplo, si definimos una variable como posiblemente una cadena o indefinida, el !operador le dice al compilador que ignore la posibilidad de que no esté definida.

Qué hace el signo de exclamación en TypeScript

Digamos que una variable se define como posiblemente nula o indefinida, así:

let x: string | undefined 

O, digamos que una función se define para aceptar un argumento opcional, así:

function printString (str ?: string) { … }

En estos casos, si intentamos hacer referencia a esa variable como un tipo definido, entonces el compilador de TypeScript nos daría un mensaje de error, como el siguiente:

Object is possibly 'undefined'. ts(2532)

Podemos usar el operador de aserción no nulo para decirle al compilador explícitamente que esta variable tiene un valor y no es nullo undefined. Revisemos algunos ejemplos para comprender mejor el signo de exclamación en TypeScript.

Ejemplo 1: Uso de una variable de tipo string | nullpara una función que aceptastring

Digamos que definimos una variable wordcon el tipo como string | null. Esto significa que a lo largo de nuestro código, wordpuede contener un stringvalor o un nullvalor.

Si intentamos usar una función solo disponible para stringtipos en word, TypeScript la rechazará porque existe una posibilidad en nuestro código que wordcontiene un nulltipo de valor:

let word : string | null = null
const num = 1
if (num) {
    word = "Hello World!"    
}
console.log(word.toLowerCase()) // Error: Object is possibly 'null'.ts(2531)

Usando el !operador de aserción no nulo, podemos decirle a TypeScript que estamos seguros de wordque nunca lo será null(o undefined), por lo que puede aplicarle con confianza funciones de cadena:

 

let word : string | null = null
const num = 1
if (num) {
    word = "Hello World!"    
}
console.log(word!.toLowerCase())

Con esta pequeña adición, el compilador ya no cree que exista la posibilidad de que wordsea nulo.

Ejemplo 2: Asignar el valor de un argumento opcional a una variable dentro de una función

En otro ejemplo, digamos que creamos una función printNameque acepta un argumento opcional personName.

Tenga en cuenta que definir un argumento de función como uso opcional ?:es lo mismo que definir el tipo como posiblemente indefinido. Por ejemplo, arg?: stringes lo mismo que arg: string | undefined.

Si intentamos reasignar ese argumento opcional personNamea otra variable de tipo string, ocurriría lo siguiente:

function printName(personName?: string) {
    const fullName: string = personName 
/** 
 * Error: Type 'string | undefined' is not assignable to type 'string'. 
 * Type 'undefined' is not assignable to type 'string'.
 */
    console.log(`The name is ${fullName}`)
}

Podemos arreglar los errores de TypeScript arrojados en nuestro fragmento anterior usando el !operador:

function printName(personName?: string) {
    const fullName: string = personName! 
    console.log(`The name is ${fullName}`)
}

Ahora, el compilador entiende que personName no puede ser nulo o indefinido, lo que lo hace asignable a type string.

Ejemplo 3: Imprimir el atributo de un argumento de objeto opcional dentro de una función

En nuestro ejemplo final, definiremos un tipo Persony una función printNameque acepta un argumento opcional de tipo Person. Veamos qué sucede si intentamos utilizar printNamepara imprimir el atributo de nombre de Person:

interface Person {
    name: string
    age: number
}

function printName(person?: Person) {
    console.log(`The name is ${person.name}`) // Error: Object is possibly 'undefined'. ts(2532)
}

Arreglemos este error de TypeScript usando nuestro !operador:

interface Person {
    name: string
    age: number
}

function printName(person?: Person) {
    console.log(`The name is ${person!.name}`)
}

Tenga en cuenta que TypeScript tiene una alternativa para hacer referencia a atributos y funciones en objetos que pueden ser nulos o indefinidos, llamada operador de encadenamiento opcional ?.. Por ejemplo, person?.nameo word?.toString()regresará undefinedsi la variable no está definida o es nula.

Sin embargo, el operador de encadenamiento opcional ?.no puede resolver los errores de TypeScript en nuestro segundo ejemplo, en el que tratamos de asignar el valor de un tipo de variable string | undefineda un tipo de variable string. Obtenga más información sobre el encadenamiento opcional en la última sección de este artículo .

Casos de uso populares para el signo de exclamación de TypeScript

Como hemos visto en nuestros ejemplos, el !operador es muy útil cuando deseamos que TypeScript trate nuestra variable como un tipo sólido. Esto evita que tengamos que manejar casos nulos o indefinidos cuando estamos seguros de que no existe tal caso.

Ahora que hemos visto algunos ejemplos para comprender mejor el signo de exclamación de TypeScript, veamos algunos casos de uso populares para este operador.

Realizar búsquedas en una matriz

Imaginemos que tenemos una matriz de objetos y queremos elegir un objeto con un valor de atributo particular, así:

interface Person {
    name: string
    age: number
    sex: string
}

const people: Person[] = [
  {
      name: 'Gran',
      age: 70,
      sex: 'female'
  },
  {
      name: 'Papa',
      age: 72,
      sex: 'male'
  },
  {
      name: 'Mom',
      age: 35,
      sex: 'female'
  },
  {
      name: 'Dad',
      age: 38,
      sex: 'male'
  }
]

const femalePerson = people.find(p => p.sex === 'female')

En nuestro fragmento anterior, TypeScript definirá el tipo de femalePersoncomo Person | undefinedporque es posible que people.findno produzca ningún resultado, en otras palabras, que no estará definido.

Sin embargo, si femalePersontiene el tipo Person | undefined, no podremos pasarlo como argumento a una función que espera el tipo Person.

Cuando realizamos búsquedas en estas matrices, a menudo confiamos en que tienen valores definidos y, por lo tanto, no creemos que exista ningún caso indefinido. Nuestro !operador puede salvarnos del manejo adicional, o innecesario, de casos nulos o indefinidos.

Agregue el operador de aserción no nulo, así:

const femalePerson = people.find(p => p.sex === 'female')!

Esto haría femalePersontener el tipo Person.

React refs y manejo de eventos

Las referencias de React se utilizan para acceder a los nodos HTML DOM renderizados o a los elementos de React. Las referencias se crean usando React.createRef<HTMLDivElement>()y luego se adjuntan al elemento usando el refatributo.

Para usar React refs, accedemos al atributo actual, ref.current. Hasta que el elemento se represente, ref.currentpodría ser null, por lo que tiene el siguiente tipo:

HTMLDivElement | null

Para adjuntar un evento a ref.current, primero tendríamos que manejar los nullvalores posibles. Aquí hay un ejemplo:

import React from 'react'

const ToggleDisplay = () => {
    const displayRef = React.createRef<HTMLDivElement>()

    const toggleDisplay = () => {
        if (displayRef.current) {
            displayRef.current.toggleAttribute('hidden')
        }
    }

    return (
        <div>
            <div class="display-panel" ref="displayRef">
                <p> some content </p>
            </div>
            <button onClick={toggleDisplay}>Toggle Content</button>
        <div>
    )
}

En el fragmento anterior, tuvimos que manejar una verificación de tipo para displayRef.currentusar una ifdeclaración antes de llamar a la toggleAttributefunción.

En la mayoría de los casos, estamos seguros de que si onClickse activa el evento del botón, nuestros elementos ya están representados. Por lo tanto, no hay necesidad de un control. Esta verificación innecesaria se puede eliminar usando el !operador, así:

const displayRef = React.createRef<HTMLDivElement>()

const toggleDisplay = () => displayRef.current!.toggleAttribute('hidden')

return (
        <div>
        ...

La desventaja de usar el signo de exclamación en TypeScript

El !operador no cambia el comportamiento de tiempo de ejecución de su código. Si el valor que ha afirmado no es nullo undefinedresulta ser nullo undefined, se producirá un error e interrumpirá la ejecución de su código.

Recuerde, la diferencia entre TypeScript y JavaScript es la aserción de tipos. En JavaScript no necesitamos ni usamos el !operador porque no hay tipo estricto.

Se puede crear una instancia de una variable de JavaScript stringy cambiarla a object, nullo numberdurante la ejecución del código. Esto deja en manos del desarrollador el manejo de los diferentes casos.

El uso del !operador elimina el "superpoder" de TypeScript de evitar errores de tipo en tiempo de ejecución. Por lo tanto, no es la mejor práctica usar el !operador.

Alternativas al uso del signo de exclamación de TypeScript

Puede usar encadenamientos opcionales o predicados de tipos como alternativas a las aserciones no nulas.

El encadenamiento opcional es una forma abreviada de TypeScript que nos permite manejar fácilmente los casos en los que la variable está definida o no. Cuando la variable no está definida o es nula, el valor al que se hace referencia por defecto es value undefined. He aquí un ejemplo de encadenamiento opcional:

interface Person {
    name: string
    age: number
    sex: string
}

function printName(person?: Person): void {
    console.log('The name of this person is', person?.name)
}

En nuestro ejemplo anterior, si personno está definido, nuestra salida de impresión sería la siguiente:

'The name of this person is undefined'

El uso de predicados de tipo en TypeScript se realiza definiendo una función que realiza una prueba booleana y devuelve un predicado de tipo en el formulario arg is Type. Aquí hay un ejemplo:

interface Person {
    name: string
    age: number
    sex: string
}

function validatePerson(person?: Person) person is Person {
    return !!person
}

Usando este tipo de predicado, primero podemos validar el objeto antes de realizar más operaciones, así:

function printName(person?: Person) {
    if (!validatePerson(person)) {
        console.log('Person is invalid')
        return
    }

    console.log(`The name is ${person.name}`)
}

Conclusión

El poder de TypeScript sobre JavaScript es la seguridad de tipos que proporciona a nuestro código . Sin embargo, es posible que a veces queramos deshabilitar las comprobaciones estrictas de tipos de TypeScript, por ejemplo, en aras de la flexibilidad o la compatibilidad con versiones anteriores. En tales casos, podemos usar el operador de aserción no nulo.

Si bien es una característica útil, lo animo a explorar métodos de aserción de tipos más seguros. Puede ir un paso más allá para evitar el uso de esta operación en su proyecto y con su equipo agregando el typescript-eslintpaquete a su proyecto y aplicando la no-non-null-assertionregla de lint .

Fuente: https://blog.logrocket.com/understanding-exclamation-mark-typescript/

#typescript 

joe biden

1617257581

Software de restauración de Exchange para restaurar sin problemas PST en Exchange Server

¿Quiere restaurar los buzones de correo de PST a Exchange Server? Entonces, estás en la página correcta. Aquí, lo guiaremos sobre cómo puede restaurar fácilmente mensajes y otros elementos de PST a MS Exchange Server.

Muchas veces, los usuarios necesitan restaurar los elementos de datos de PST en Exchange Server, pero debido a la falta de disponibilidad de una solución confiable, los usuarios no pueden obtener la solución. Háganos saber primero sobre el archivo PST y MS Exchange Server.

Conozca PST y Exchange Server

PST es un formato de archivo utilizado por MS Outlook, un cliente de correo electrónico de Windows y muy popular entre los usuarios domésticos y comerciales.

Por otro lado, Exchange Server es un poderoso servidor de correo electrónico donde todos los datos se almacenan en un archivo EDB. Los usuarios generalmente guardan la copia de seguridad de los buzones de correo de Exchange en el archivo PST, pero muchas veces, los usuarios deben restaurar los datos del archivo PST en Exchange. Para resolver este problema, estamos aquí con una solución profesional que discutiremos en la siguiente sección de esta publicación.

Un método profesional para restaurar PST a Exchange Server

No le recomendamos que elija una solución al azar para restaurar los datos de PST en Exchange Server. Por lo tanto, al realizar varias investigaciones, estamos aquí con una solución inteligente y conveniente, es decir, Exchange Restore Software. Es demasiado fácil de manejar por todos los usuarios y restaurar cómodamente todos los datos del archivo PST a Exchange Server.

Funciones principales ofrecidas por Exchange Restore Software

El software es demasiado simple de usar y se puede instalar fácilmente en todas las versiones de Windows. Con unos pocos clics, la herramienta puede restaurar los elementos del buzón de Exchange.

No es necesario que MS Outlook restaure los datos PST en Exchange. Todos los correos electrónicos, contactos, notas, calendarios, etc. se restauran desde el archivo PST a Exchange Server.

Todas las versiones de Outlook son compatibles con la herramienta, como Outlook 2019, 2016, 2013, 2010, 2007, etc. La herramienta proporciona varios filtros mediante los cuales se pueden restaurar los datos deseados desde un archivo PST a Exchange Server. El programa se puede instalar en todas las versiones de Windows como Windows 10, 8.1, 8, 7, XP, Vista, etc.

Descargue la versión de demostración del software de restauración de Exchange y analice el funcionamiento del software restaurando los primeros 50 elementos por carpeta.

Líneas finales

No existe una solución manual para restaurar los buzones de correo de Exchange desde el archivo PST. Por lo tanto, hemos explicado una solución fácil e inteligente para restaurar datos de archivos PST en Exchange Server. Simplemente puede usar este software y restaurar todos los datos de PST a Exchange Server.

Más información:- https://www.datavare.com/software/exchange-restore.html

#intercambio de software de restauración #intercambio de restauración #buzón del servidor de intercambio #herramienta de restauración de intercambio

Comprender El Principio De inversión De Dependencia En TypeScript

Siempre que estamos creando software, a los desarrolladores generalmente les gusta dividir los problemas grandes en problemas más pequeños. Implementamos las soluciones a los subproblemas en componentes o módulos, luego integramos esos componentes para crear un sistema que resuelve el problema original.

Una de las cosas que determina la calidad de los sistemas y aplicaciones que construimos es el grado de interdependencia entre los módulos de software que componen el proyecto. Este grado de interdependencia se denomina dependencia o acoplamiento.

Por ejemplo, si tenemos un módulo (o clase) A que usa otro módulo (o clase) B, decimos que A depende de B, así:

  class B {
  }
  class A {
      private b = new B();
  }
  // class A depends on class B

A continuación se muestra un diagrama que representa la relación entre A y B:

Pero, antes de que podamos hablar sobre el Principio de Inversión de Dependencia, primero debemos analizar el concepto de acoplamiento débil frente a estrecho.

Acoplamiento bajo (o suelto) frente a acoplamiento apretado

Uno de los signos de una aplicación bien estructurada (o sistema informático en general) es tener una interdependencia mínima (acoplamiento bajo) entre los componentes o módulos del sistema. No es deseable un sistema de componentes estrechamente acoplados.

Uno de los aspectos negativos de un sistema estrechamente acoplado es que el cambio en un módulo tendrá un efecto dominó de cambios en otros módulos que dependen del módulo modificado. Otro aspecto negativo es que un módulo puede volverse difícil de reutilizar y probar, porque se deben incluir sus módulos dependientes.

El principio de inversión de dependencia

El Principio de Inversión de Dependencia es un principio que nos ayuda a acoplar módulos de software de forma flexible. Se llegó al principio después de muchos años de acoplar módulos de software por ingenieros de software profesionales, establece que:

  • Los módulos de alto nivel no deberían importar nada de los módulos de bajo nivel. Ambos deberían depender de abstracciones.
  • Las abstracciones no deberían depender de implementaciones concretas. Las implementaciones concretas deberían depender de abstracciones

Dependiendo de las abstracciones

Cuando abstraemos, podemos decir que estamos tratando solo con la idea general de algo sin preocuparnos por los detalles. Una forma importante de abstraer las cosas es mediante el uso de una interfaz.

El primer principio establece que tanto los módulos de alto nivel como los de bajo nivel deben depender de las mismas abstracciones. Si un módulo depende de una abstracción, por ejemplo, una interfaz o una clase abstracta, podemos cambiar la dependencia de la que depende por cualquier otra implementación que se adhiera a la interfaz.

Para una analogía de la vida real, tome, por ejemplo, el enchufe de un cargador de computadora portátil a continuación:

Este enchufe se puede conectar a cualquier enchufe siempre que el enchufe satisfaga la "interfaz" de los tres pines. De esta manera, el enchufe se puede usar con una variedad de enchufes, siempre que cumplan con los requisitos de la interfaz.

Un ejemplo de inversión de dependencia en TypeScript

Supongamos que tenemos una Loggerclase para registrar información en nuestro proyecto, definida en un archivo logger.tsde la siguiente manera:

export class Logger {
  log(message: string) {
    console.log(message);
  }
  error(message: string) {
    console.error(message);
  }
}

Estamos exportando la Loggerclase, ya que se espera que se use en otros lugares. Y lo estamos usando en otro módulo ubicado en un archivo llamado user-service.ts:

import { Logger } from "./logger"; // this module depends on concrete implementatioon of logger

class UserService {
  private logger = new Logger();

  async getAll() {
    try {
      this.logger.log('Retrieving all users...');
      return [];
    } catch (error: any) {
      this.logger.log(`An error occurred: ${error?.message}`);
      throw new Error('Something went wrong')
    }
  }
}

Representemos la relación entre ambas clases de la siguiente manera:

La UserServiceclase depende de la Loggerclase. Esto se hace evidente en primer lugar por el hecho de que tenemos que importar la Loggerclase a la UserServiceclase.

Esta línea private logger = new Logger();también revela que UserServiceestá estrechamente relacionado con la implementación actual de Logger. Depende de una implementación concreta.

Inyectando dependencias

UserServiceno se puede probar por separado sin el Logger. Una forma de mejorar la capacidad de prueba de UserServicees cambiar la forma en que suministramos el Loggerobjeto.

Actualmente, un Loggerobjeto es instanciado UserServicepor la línea private logger = new Logger();. Podemos transferir la tarea de crear el objeto a otra parte de nuestro código y simplemente usamos el objeto directamente. Es decir, otra persona crea el objeto de dependencia y lo inyecta en UserService. Esto se llama inyección de dependencia.

Un ejemplo de cómo hacer esto se muestra en el siguiente fragmento de código:

import { Logger } from "./logger";

class UserService {
  private logger: Logger;
  // the constructor receives the object to inject from another source
  constructor(logger: Logger) {
    this.logger = logger;
  }
  async getAll() {
    try {
      this.logger.log("Retrieving all users...");
      return [];
    } catch (error: any) {
      this.logger.log(`An error occurred: ${error?.message}`);
      throw new Error("Something went wrong");
    }
  }
}

La Loggerinstancia ahora se inyecta en la UserServiceclase a través del constructor, pero aún depende de una implementación concreta de Logger, porque la loggerpropiedad aún se escribe como Logger.

Aplicar el principio de inversión de dependencia en TypeScript

Como sugiere el principio, queremos asegurarnos de que UserServiceambos Loggerdependan de abstracciones. No queremos importar nada de la clase de nivel inferior ( Logger, en este caso) a la clase de nivel superior ( UserService).

Introduzcamos un interfacey dejemos que UserServicedependa de él:

export interface ILogger {
  log(message: string): void;
  error(message: string): void;
}

class UserService {
  private logger: ILogger;
  constructor(logger: ILogger) {
    this.logger = logger;
  }
  async getAll() {
    try {
      this.logger.log("Retrieving all users...");
      return [];
    } catch (error: any) {
      this.logger.log(`An error occurred: ${error?.message}`);
      throw new Error("Something went wrong");
    }
  }
}

Arriba, tenemos una ILoggerinterfaz definida en UserService. Este servicio define lo que se UserServiceespera de un registrador; no está vinculado a una clase de registrador específica.

Cualquier clase que implemente la interfaz se puede inyectar en UserService. Tenga en cuenta que la ILoggerinterfaz no tiene que definirse en el user-service.tsarchivo, puede (y debe) extraerse en su propio archivo.

Ahora, actualizamos la Loggerclase para implementar la interfaz definida por UserService:

import { ILogger } from "./user-service";

export class Logger implements ILogger {
  log(message: string) {
    console.log(message);
  }
  error(message: string) {
    console.error(message);
  }
}

Tenga en cuenta que UserServiceno está importando nada Loggeren su implementación, y ambas clases dependen de una interfaz (una abstracción).

Entonces podemos hacer esto en cualquier lugar que queramos usar UserService:

...
// inject any class that implements ILogger into UserService
const userService = new UserService(new Logger()) 
userService.getAll()
...

El diagrama de clases se verá así ahora:

Observe la dirección de las flechas. En el diagrama de clases anterior, había una flecha de UserServicea Loggerque indica que depende de Logger. Ahora tenemos una flecha desde UserServicea la interfaz ILogger. Además, tenemos una flecha de Loggera ILogger. Ambos dependen de una abstracción.

Hemos invertido con éxito la dirección de la dependencia. La inversión no significa que la capa de nivel inferior dependa directamente del nivel de nivel superior, significa que ambas capas deberían depender de abstracciones, y estas abstracciones exponen el comportamiento que necesitan las capas de nivel superior.

Intercambio de diferentes implementaciones

Ahora, para mostrar uno de los beneficios de aplicar el principio de inversión de dependencia, supongamos que nuestro proyecto es un proyecto de Node.js y queremos usar una biblioteca de registro de terceros para el registro. Winston es una de las bibliotecas de registradores populares que podemos elegir. Debido a que esta publicación no es una publicación sobre el registro, no entraré en detalles sobre cómo usar Winston.

Digamos que lo instaló winstony configuró como se describe en los documentos , puede crear una clase que implemente ILoggerde la siguiente manera en un archivo llamado winston-logger.ts:

import { ILogger } from "./user-service";
import * as winston from "winston";

export class WinstonLogger implements ILogger {
  private winstonLogger: winston.Logger;

  constructor() {
    this.winstonLogger = winston.createLogger({
      transports: [
        new winston.transports.File({
          format: winston.format.combine(
            winston.format.json(),
            winston.format.timestamp()
          ),
          filename: "logs/combined.log",
        }),
      ],
    });
  }

  log(message: string): void {
    this.winstonLogger.log(message);
  }
  error(message: string): void {
    this.winstonLogger.error(message);
  }
}

Configuramos el winston.transports.Filetransporte para que los registros se puedan guardar en un archivo ubicado en la ruta del archivo logs/combined.log, relativa a la raíz del proyecto. La WinstonLoggerclase también implementa la ILoggerinterfaz.

UserServicepuede hacer uso de WinstonLogger, porque se adhiere a la interfaz que UserServiceimplementa de la siguiente manera:

const userService = new UserService(new WinstonLogger())
userService.getAll()

El diagrama de clases que representa la relación entre las clases se ve así:

Suponga que después de un tiempo decide que la winstonbiblioteca de registradores no es la mejor para su proyecto y quiere usar Bunyan , ¿qué hace? Solo necesita crear una BunyanLoggerclase que implemente la ILoggerinterfaz y esté lista para ser utilizada por UserService.

La aplicación del principio de inversión de dependencia también garantiza que no estemos atados a una biblioteca de registro de terceros específica. No tenemos el control de la biblioteca, pero tenemos el control de cómo nuestro código de proyecto interactúa con él.

Conclusión

En este artículo, hemos explicado qué es una dependencia y por qué queremos un acoplamiento débil entre los componentes o módulos que componen nuestra aplicación TypeScript. También vimos el Principio de Inversión de Dependencia, un ejemplo práctico de cómo aplicarlo y cómo nos permite intercambiar implementaciones fácilmente.

El principio de inversión de dependencia es uno de los principios de los populares principios SOLID, que es un acrónimo de los primeros cinco principios de diseño orientado a objetos de Robert C. Martin. 

Enlace: https://blog.logrocket.com/understanding-dependency-inversion-principle-typescript/ 

#typescript 

joe biden

1617255938

¿Cómo migrar los buzones de correo de Exchange a la nube de Office 365?

Si tiene problemas para migrar los buzones de correo de Exchange a Office 365, debe leer este artículo para saber cómo migrar los buzones de correo de Exchange EDB a Office 365. Al migrar a Office 365, los usuarios pueden acceder a sus buzones de correo desde cualquier lugar y desde cualquier dispositivo.

En esta publicación, explicaremos las razones detrás de esta migración y una solución profesional para migrar de Exchange a Office 365.

Razones para migrar Exchange Server a la nube de Office 365

Office 365 apareció por primera vez en 2011 y, dado que se considera la mejor plataforma para aquellas organizaciones que desean administrar todo su sistema de correo electrónico en la nube. Estas son las características clave de Office 365:

  1. Permite trabajar desde cualquier lugar y desde cualquier lugar.
  2. No se preocupe por el spam y el malware.
  3. La seguridad proporcionada por Office 365 es altamente confiable.
  4. Controla el costo total y brinda flexibilidad financiera.
  5. Todas las actualizaciones y mejoras son administradas por Microsoft.

¿Cómo migrar los buzones de correo de Exchange a Office 365?

Hay varias formas manuales de migrar los buzones de correo de Exchange EDB a Office 365, pero para evitar estos complicados y prolongados procedimientos, presentamos una solución de terceros, es decir, la herramienta de migración de Exchange, que es automatizada y directa para la migración de Exchange a Office 365. La herramienta funciona rápidamente y migra todos los elementos del buzón de Exchange Server a Office 365.

La herramienta de migración de Datavare Exchange es demasiado fácil de usar y ofrece pasos sencillos para migrar EDB a Office 365:

  1. Descargue e instale el software en su sistema.
  2. Agregue el archivo EDB de Exchange con el botón Examinar.
  3. Seleccione exportar a buzones de correo de Office 365.
  4. Proporcione los detalles de inicio de sesión de la cuenta de Office 365.
  5. Seleccione la carpeta y presione el botón Finalizar.

Por lo tanto, todos sus buzones de correo de Exchange EDB ahora se migran a Office 365.
Nota: puede usar filtros para migrar los elementos de datos deseados de la cuenta de Exchange a la de Office 365

Líneas finales

Este blog le indica una solución profesional para la migración de buzones de correo de Exchange a la cuenta de Office 365. Dado que las soluciones manuales son complicadas, sugerimos la herramienta de migración de Exchange, que es demasiado simple de usar. Los usuarios no se enfrentan a problemas al operar el programa. La mejor parte de este software es que no necesita habilidades técnicas para realizar la migración. Se puede comprender el funcionamiento del software descargando la versión de demostración que permite la migración de los primeros 50 elementos por carpeta.

Más información:- https://www.datavare.com/software/edb-migration.html

#herramienta de migración de intercambio #migración de intercambio #migrar buzones de correo de exchange