Crear objetos de base de los tipos de transcripción

0

Pregunta

Para no decir que tengo este tipo de

type foo = {
 go: string;
 start: string;
}

¿Cómo puedo dynamicaly hecho una función que devolverá

{ go: '', start: '' }

Es allí cualquier manera en el Tipo de secuencia de Comandos que puede generar dinámicamente un objeto vacío basada exclusivamente solo tipo? O esto es imposible porque no podemos simplemente bucle

Yo estaba pensando en algo como esto

function generate<T>(T)<T>  {
 const obj = {}
 for (const key of keyof T) {
   obj[key] = ''
 }
 return obj
}
typescript
2021-11-23 19:36:25
2

Mejor respuesta

2

Cuando se ejecuta el Manuscrito compilador (tsc) para transpile Manuscrito código ejecutable de JavaScript, el lenguaje es estático y que tipo de sistema se borran. Por lo que su Foo tipo (cambia a mayúsculas para satisfacer TS convenciones de nomenclatura) no está presente en cualquier formulario en tiempo de ejecución. No hay nada que usted puede iterar a través de obtener las llaves go y start.


La forma más sencilla de conseguir que algo suceda en el tiempo de ejecución es escribir el código JavaScript necesario para hacerlo, y para asegurarse de que el Manuscrito compilador puede dar el fuerte de tipos que necesita mientras está escribiendo. Esta es básicamente la inversa de lo que estamos tratando de hacer.

En tu caso: ¿qué generate() para trabajar en tiempo de ejecución? Así, si asumimos que los valores generados por generate() serán objetos de la celebración de sólo stringvalores de las propiedades, entonces tenemos que pasar una lista de las claves del objeto. ¿Qué tal si escribimos generate() para hacer eso, y luego definir Foo en términos de la salida de generate() en lugar de que sea al revés?

Por ejemplo:

function generate<K extends PropertyKey>(...keys: K[]) {
  return Object.fromEntries(keys.map(k => [k, ""])) as { [P in K]: string };
}

const myFooObject = generate("go", "start");

type Foo = typeof myFooObject;
/* type Foo = {
    go: string;
    start: string;
} */

console.log(myFooObject)
/* {
  "go": "",
  "start": ""
} */

Aquí generate() es un genérico función que toma una lista de claves (de tipo K) y produce un valor de un tipo con claves en K y los valores de tipo string. Que {[P in K]: string} es un asignada tipo equivalente a Record<K, string> el uso de la Record<K, V> tipo de utilidad.

La aplicación utiliza Object.fromEntries() para construir el objeto, y el tipo de retorno es afirmado ser el tipo correcto porque Manuscrito ve Object.fromEntries() como devolver un tipo que es demasiado amplia para nuestros propósitos.

De todos modos cuando te llame const myFooObject = generate("go", "start")produce un valor de tipo {go: string; start: string}, que es el mismo que el de su Foo tipo. Así que podemos definir Foo como type Foo = typeof myFooObject en lugar de hacerlo manualmente. Usted puede hacerlo manualmente, pero el punto que estoy mostrando aquí es que es mucho más fácil escribir en SECO de código en la Máquina si usted comienza con los valores y generar tipos de ellos, en lugar de tratar de hacerlo de la otra manera alrededor.


De nuevo, si usted está utilizando el Manuscrito del compilador tsc como-es, entonces, el tipo de borrado le impide escribir generate() a partir de la definición de Foo. Pero...

Si usted está dispuesto a añadir un paso de compilación para su proyecto y realizar la generación de código mediante el Manuscrito compilador API o algo por el estilo, a continuación, puede hacer cosas arbitrarias con tipos. Hay bibliotecas que hacer cosas similares a lo que usted desea; por ejemplo, ts-auto-simulacro de reclamaciones para generar objetos ficticios dado un tipo de objeto, que se parece exactamente el caso de uso.

Un extra construir paso podría ser un enfoque razonable para usted, pero si vas por ese camino debe tener en cuenta que no estás usando simplemente el Manuscrito más (y por lo tanto el tema es, probablemente, fuera del ámbito de una pregunta con sólo un Manuscrito de la etiqueta).

Patio enlace a código

2021-11-25 04:07:53
1

Usted podría hacer es genérica, como por ejemplo este:

type foo<T extends string = string> = {
    go: T;
    start: T;
}

const test: foo<''> = {
    go: '',
    start: '',
};

Manuscrito Zona De Juegos Infantil

2021-11-23 19:47:19

En otros idiomas

Esta página está en otros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Slovenský
..................................................................................................................