TypeScript Español
TypeScript Español
TypeScript
Microsoft pondrá a disposición esta Especificación bajo el Acuerdo de Especificación Final de la Open Web
Foundation Versión 1.0 ( " OWF 1.0 " ) a partir del 1 de octubre, 20 12. El OWF 1.0 está disponible
en http://www.openwebfoundation.org/legal/the- acuerdos owf-1-0 / owfa-1-0 .
Tabla de contenido
1 Introducción
1.1 Declaraciones ambientales
1.2 Tipos de funciones
1.3 Tipos de objeto
1.4 Subtipo estructural
1.5 Mecanografía contextual
1.6 clases
1.7 Tipos de enumeración
1.8 Sobrecarga en los parámetros de cadena
1.9 Tipos genéricos y funciones
1.10 espacios de nombres
1.11 Módulos
2 conceptos básicos
2.1 Convenciones de gramática
2.2 Nombres
2.2.1 Palabras reservadas
2.2.2 Nombres de propiedad
2.2.3 Nombres de propiedades calculadas
2.3 Declaraciones
2.4 alcances
3 tipos
3.1 El cualquier tipo any
3.2 Tipos primitivos
3.2.1 El tipo de número number
3.2.2 El tipo booleano boolean
3.2.3 El tipo de cadena string
3.2.4 El tipo de símbolo simbol
3.2.5 El tipo vacío void
3.2.6 El tipo nulo null
3.2.7 El tipo indefinido undefined
3.2.8 Tipos de enumeración enum
3.2.9 Tipos literales de cadena
3.3 Tipos de objetos
3.3.1 Referencias de tipo con nombre
3.3.2 Tipos de matriz array
3.3.3 Tipos de tuplas tuples
3.3.4 Tipos de funciones
3.3.5 Tipos de constructor
3.3.6 Miembros
3.4 Tipos de unión
3.5 Tipos de intersección
3.6 Parámetros de tipo
3.6.1 Listas de parámetros de tipo
3.6.2 Listas de argumentos de tipo
3.6.3 Este tipo
3.7 Tipos con nombre
3.8 Especificación de tipos
3.8.1 Tipos predefinidos
3.8.2 Referencias de tipo
3.8.3 Literales de tipo de objeto
3.8.4 Literales de tipo de matriz
3.8.5 Literales tipo tupla
3.8.6 Literales tipo unión
3.8.7 Literales de tipo de intersección
3.8.8 Literales de tipo de función
3.8.9 Literales de tipo de constructor
3.8.10 Consultas de tipo
3.8.11 Referencias de este tipo
3.9 Especificación de miembros
3.9.1 Firmas de propiedad
3.9.2 Firmas de llamadas
3.9.3 Construir firmas
3.9.4 Firmas de índice
3.9.5 Firmas de métodos
3.10 Alias tipo
3.11 Relaciones de tipo
3.11.1 Miembros aparentes
3.11.2 Tipo e identidad del miembro
3.11.3 Subtipos y supertipos
3.11.4 Compatibilidad de asignación
3.11.5 Exceso de propiedades
3.11.6 Creación de instancias de firma contextual
3.11.7 Inferencia de tipo
3.11.8 Tipos recursivos
3.12 Tipos ensanchados
4 expresiones
4.1 Valores y referencias
4.2 La palabra clave this
4.3 identificadores
4.4 Literales
4.5 Literales de objetos
4.6 Literales de matriz
4.7 Literales de plantilla
4.8 Paréntesis
4.9 La súper palabra clave super keyword
4.9.1 Super llamadas super calls
4.9.2 Super acceso a la propiedad access
4.10 Expresiones de funciones
4.11 Funciones de flecha
4.12 Expresiones de clase class
4.13 Acceso a la propiedad
4.14 El nuevo operador
4.15 Llamadas de función
4.15.1 Resolución de sobrecarga overload
4.15.2 Inferencia de argumento de tipo inference
4.15.3 Ambigüedades gramaticales
4.16 Afirmaciones de tipo assertions
4.17 Expresiones JSX
4.18 Operadores unarios unary
4.18.1 Los operadores ++ y -
4.18.2 Los operadores +, - y ~
4.18.3 El! operador
4.18.4 El operador de eliminación delete
4.18.5 El operador vacío void
4.18.6 El tipo de operador typeof
4.19 Operadores binarios
4.19.1 El *, /,%, -, <<, >>, >>>, &, ^ y | operadores
4.19.2 El operador +
4.19.3 Los operadores <,>, <=,> =, == ,! =, === y! ==
4.19.4 La instancia del operador instanceof
4.19.5 El operador in
4.19.6 El operador &&
4.19.7 El || operador
4.20 El operador condicional
4.21 Operadores de asignación
4.21.1 Asignación de desestructuración
4.22 El operador de coma
4.23 Expresiones de tipo contextual contextually
4.24 Guardias tipo guards
5 declaraciones
5.1 bloques
5.2 Declaraciones variables
5.2.1 Declaraciones de variables simples
5.2.2 Desestructuración de declaraciones de variables
5.2.3 Tipo implícito impliied
5.3 Declaraciones de Let y Const
5.4 Declaraciones If, Do y While
5.5 Para declaraciones for
5.6 Declaraciones for-in
5.7 Declaraciones for-of
5.8 Continuar declaraciones continue
5.9 Declaraciones de ruptura break
5.10 Declaraciones de devolución return
5.11 Con declaraciones with
5.12 Cambiar declaraciones switch
5.13 Declaraciones de lanzamiento throw
5.14 Intentar declaraciones try
6 funciones
6.1 Declaraciones de funciones
6.2 Sobrecargas de funciones
6.3 Implementaciones de funciones
6.4 Declaraciones de parámetros de desestructuración
6.5 Funciones genéricas
6.6 Generación de código
6.7 Funciones del generador
6.8 Funciones asincrónicas
6.9 Funciones de protección de tipo
7 interfaces
7.1 Declaraciones de interfaz
7.2 Fusión de declaraciones merging
7.3 Interfaces que amplían clases
7.4 Verificaciones de tipo dinámico checks
8 clases
8.1 Declaraciones de clase
8.1.1 Especificación de patrimonio de clase heritage
8.1.2 Cuerpo de clase body
8.2 Miembros
8.2.1 Instancia y miembros estáticos
8.2.2 Accesibilidad
8.2.3 Herencia y anulación
8.2.4 Tipos de clase
8.2.5 Tipos de funciones de constructor
8.3 Declaraciones del constructor
8.3.1 Parámetros del constructor
8.3.2 Super llamadas
8.3.3 Constructores automáticos
8.4 Declaraciones de miembros de la propiedad
8.4.1 Declaraciones de variables miembro
8.4.2 Declaraciones de funciones del miembro
8.4.3 Declaraciones de acceso de miembros
8.4.4 Declaraciones de propiedades dinámicas
8.5 Declaraciones de miembros de índice
8.6 Decoradores
8.7 Generación de código
8.7.1 Clases sin cláusulas extendidas
8.7.2 Clases con cláusulas extendidas
9 enumeraciones
9.1 Declaraciones de enumeración
9.2 Miembros de Enum
9.3 Fusión de declaraciones
9.4 Declaraciones de enumeración constante
9.5 Generación de código
10 espacios de nombres
10.1 Declaraciones de espacio de nombres
10.2 Cuerpo del espacio de nombres
10.3 Declaraciones de alias de importación
10.4 Declaraciones de exportación
10.5 Fusión de declaraciones
10.6 Generación de código
11 Scripts y módulos
11.1 Programas y archivos fuente
11.1.1 Dependencias de archivos fuente
11.2 Guiones
11.3 Módulos
11.3.1 Nombres de módulos
11.3.2 Declaraciones de importación
11.3.3 Importar declaraciones requeridas
11.3.4 Declaraciones de exportación
11.3.5 Asignaciones de exportación
11.3.6 Módulos CommonJS
11.3.7 Módulos AMD
12 ambientes
12.1 Declaraciones ambientales
12.1.1 Declaraciones de variables ambientales
12.1.2 Declaraciones de función ambiental
12.1.3 Declaraciones de clase ambiental
12.1.4 Declaraciones de enumeración ambiental
12.1.5 Declaraciones de espacio de nombres ambientales
12.2 Declaraciones de módulo ambiental
Una gramática
A.1 Tipos
A.2 Expresiones
A.3 Declaraciones
A.4 Funciones
A.5 Interfaces
A.6 Clases
A.7 Enums
A.8 Espacios de nombres
A.9 Scripts y módulos
A.10 Ambientes
1 Introducción
Las aplicaciones de JavaScript , como el correo electrónico web , los mapas, la edición de documentos y las herramientas
de colaboración se están convirtiendo en una parte cada vez más importante de la informática
cotidiana. Diseñamos TypeScript para satisfacer las necesidades de los equipos de programación de JavaScript que crean y
mantienen grandes programas de JavaScript. TypeScript ayuda a los equipos de programación a definir interfaces entre
componentes de software y a obtener información sobre el comportamiento de las bibliotecas JavaScript
existentes. TypeScript también permite a los equipos reducir los conflictos de nombres al organizar su código en módulos
cargables dinámicamente. Mecanografiado ' s sistema de tipo opcional permite a los programadores de JavaScript para
utilizar herramientas de desarrollo altamente productivas y prácticas: comprobación estática, navegación basada en
símbolos, la finalización de instrucciones y el código de re-factoring.
TypeScript es un azúcar sintáctico para JavaScript. La sintaxis de TypeScript es un superconjunto de la sintaxis
de ECMAScript 2015 (ES2015 ). Cada programa de JavaScript también es un programa TypeScript. El compilador
de TypeScript solo realiza transformaciones locales de archivo en los programas de TypeScript y no reordena las variables
declaradas en TypeScript. Esto conduce a la salida de JavaScript que coincide estrechamente con la entrada
de TypeScript. TypeScript no transforma los nombres de las variables, lo que hace que la depuración directa de JavaScript
emitida sea manejable. TypeScript opcionalmente proporciona mapas de origen, lo que permite la depuración a nivel de
origen. Las herramientas de TypeScript suelen emitir JavaScript al guardar el archivo, preservando el ciclo de prueba,
edición y actualización comúnmente utilizado en el desarrollo de JavaScript.
La sintaxis de TypeScript incluye todas las características de ECMAScript 2015 , incluidas las clases y los módulos , y ofrece
la capacidad de traducir estas características en código compatible con ECMAScript 3 o 5.
Las clases permiten a los programadores expresar patrones comunes orientados a objetos de una manera estándar,
haciendo que características como la herencia sean más legibles e interoperables. Los módulos permiten a los
programadores organizar su código en componentes y evitar conflictos de
nombres. El compilador TypeScript proporciona opciones de generación de código de módulo que admiten la carga
estática o dinámica del contenido del módulo.
El sistema de tipos TypeScript permite a los programadores expresar límites sobre las capacidades de los objetos
JavaScript y utilizar herramientas que imponen estos límites. Para minimizar el número de anotaciones necesarias para que
las herramientas sean útiles, el sistema de tipos TypeScript hace un uso extensivo de la inferencia de tipos. Por ejemplo, a
partir de la siguiente declaración, TypeScript inferirá que la variable ' i ' tiene el número de tipo.
var i = 0;
TypeScript inferirá de la siguiente definición de función que la función f tiene una cadena de tipo de retorno.
función f () { return " hola " ; }
Para beneficiarse de esta inferencia, un programador puede usar el servicio de lenguaje TypeScript. Por ejemplo, un editor
de código puede incorporar el servicio de lenguaje TypeScript y usar el servicio para encontrar los miembros de un objeto
de cadena como en la siguiente captura de pantalla.
En este ejemplo, el programador se beneficia de la inferencia de tipos sin proporcionar anotaciones de tipo. Sin embargo,
algunas herramientas beneficiosas requieren que el programador proporcione anotaciones de tipo. En TypeScript,
podemos expresar un requisito de parámetro como en el siguiente fragmento de código.
f({}); // Error
f("hello"); // Ok
function f(s) {
return s;
}
En la salida de JavaScript, todas las anotaciones de tipo se han borrado. En general, TypeScript borra toda la información
de tipo antes de emitir JavaScript.
1.1 Declaraciones ambientales
Una declaración ambiental introduce una variable en un ámbito de TypeScript, pero tiene cero impacto en el programa
JavaScript emitido. Los programadores pueden usar declaraciones ambientales para decirle al compilador TypeScript que
algún otro componente proporcionará una variable. Por ejemplo, por defecto, el compilador TypeScript imprimirá un error
para el uso de variables indefinidas. Para agregar algunas de las variables comunes definidas por los navegadores,
un programador de TypeScript puede usar declaraciones ambientales. El siguiente ejemplo declara
el objeto ' documento ' proporcionado por los navegadores. Debido a que la declaración no especifica un tipo, se
infiere el tipo ' any ' . El tipo ' cualquiera ' significa que una herramienta no puede asumir nada sobre la forma o el
comportamiento del objeto del documento. Algunos de los ejemplos a continuación ilustrarán cómo los programadores
pueden usar tipos para caracterizar aún más el comportamiento esperado de un objeto.
El compilador TypeScript no incluye por defecto una interfaz para jQuery, por lo que para usar jQuery, un programador
podría proporcionar una declaración como:
declare var $;
Sección 1.3 provee s un ejemplo más extenso de cómo un programador puede añadir información de tipo F o jQuery y
otras bibliotecas.
1.2 Tipos de funciones
Las expresiones de función son una característica poderosa de JavaScript. Permiten a las definiciones de funciones para
crear cierres: funciones que capturan información del ámbito léxico que rodea la función ' definición s. Los cierres son
actualmente JavaScript ' única manera de hacer cumplir la encapsulación de datos s. Al capturar y utilizar variables de
entorno, un cierre puede retener información a la que no se puede acceder desde fuera del cierre. Los programadores de
JavaScript a menudo usan cierres para expresar controladores de eventos y otras devoluciones de llamada asíncronas, en
las que otro componente de software, como el DOM, volverá a llamar a JavaScript a través de una función de controlador.
Los tipos de función de TypeScript hacen posible que los programadores expresen la firma esperada de una función. Una
firma de función es una secuencia de tipos de parámetros más un tipo de retorno. El siguiente ejemplo utiliza tipos de
función para expresar los requisitos de firma de devolución de llamada de un mecanismo de votación asíncrono.
vote("BigPig",
function(result: string) {
if (result === "BigPig") {
// ...
}
}
);
lo que significa que el segundo parámetro es una función que devuelve el tipo ' any ' que tiene un solo parámetro de
tipo ' string ' llamado ' result ' .
1.3 Tipos de objeto
Los programadores de TypeScript usan tipos de objetos para declarar sus expectativas sobre el comportamiento de los
objetos . El siguiente código utiliza un literal de tipo de objeto para especificar el tipo de retorno de la
función ' MakePoint ' .
Los programadores pueden dar nombres a los tipos de objetos; llamamos interfaces de tipos de objetos con
nombre . Por ejemplo, en el siguiente código, una interfaz declara un campo obligatorio (name) y un campo opcional
(favoriteColor).
interface Friend {
name: string;
favoriteColor?: string;
}
function add(friend: Friend) {
var name = friend.name;
}
El siguiente fragmento de código captura un pequeño subconjunto del comportamiento de jQuery, lo suficiente como
para usar jQuery de una manera simple.
interface JQuery {
text(content: string);
}
interface JQueryStatic {
get(url: string, callback: (data: string) => any);
(query: string): JQuery;
}
$.get("http://mysite.org/divContent",
function (data: string) {
$("div").text(data);
}
);
La interfaz ' J Query Static ' hace referencia a otra interfaz: ' J Query ' . Esta interfaz representa una colección de uno o más
elementos DOM. La biblioteca j Query puede realizar muchas operaciones en dicha colección, pero en este ejemplo, el
cliente jQuery solo necesita saber que puede establecer el contenido de texto de cada elemento jQuery en una colección
pasando un anillo st al método ' text ' . La interfaz ' J Query Static ' también contiene un método, ’get’ , que realiza una
operación de obtención de Ajax en la URL proporcionada y hace los arreglos para invocar la devolución de llamada
proporcionada al recibir una respuesta.
La firma desnuda indica que las instancias de la interfaz son invocables. Este ejemplo ilustra que los tipos de
función TypeScript son solo casos especiales de tipos de objeto TypeScript. Específicamente, los tipos de función son los
tipos de objetos que contienen uno o más llamada firma s . Por esta razón, podemos escribir cualquier función ty pe como
un tipo de objeto literal. El siguiente ejemplo usa ambos formularios para describir el mismo tipo.
Esta firma denota que se puede pasar una función como parámetro de la función ' $ ' . Cuando una función se pasa a ' $ ' ,
la biblioteca jQuery invocará esa función cuando un documento DOM esté listo. Debido a que TypeScript admite la
sobrecarga, las herramientas pueden usar TypeScript para mostrar todas las firmas de funciones disponibles con sus
sugerencias de documentación y proporcionar la documentación correcta una vez que una función ha sido llamada con
una firma particular.
Un cliente típico no necesitaría agregar ningún tipo de escritura adicional, sino que podría usar un tipo de escritura
proporcionado por la comunidad para descubrir (a través de la finalización de la declaración con sugerencias de
documentación) y verificar (a través de la comprobación estática) el uso correcto de la biblioteca, como en la siguiente
captura de pantalla.
1.4 Subtipo estructural
Los tipos de objetos se comparan estructuralmente. Por ejemplo, en el fragmento de código a continuación,
la clase ' CPoint ' coincide con la interfaz ' Punto ' porque ' Punto C ' tiene todos los miembros requeridos
de ' Punto ' . Una clase puede declarar opcionalmente que implementa una interfaz, de modo que el compilador verificará
la declaración de compatibilidad estructural. El ejemplo también ilustra que un tipo de objeto puede coincidir con el tipo
inferido de un literal de objeto, siempre que el literal de objeto suministre todos los miembros requeridos.
interface Point {
x: number;
y: number;
}
1.5 Mecanografía contextual
Normalmente, la inferencia de tipos de TypeScript procede "de abajo hacia arriba " : desde las hojas de un árbol de
expresión hasta su raíz. En el siguiente ejemplo, TypeScript infiere ' número ' como el tipo de retorno de la
función ' mul ' al hacer fluir la información del tipo de abajo hacia arriba en la expresión de retorno.
Sin embargo, en algunos contextos limitados, la inferencia procede "de arriba abajo " del contexto de una
expresión. Cuando esto sucede, se llama tipificación contextual. La escritura contextual ayuda a las herramientas a
proporcionar información excelente cuando un programador está usando un tipo pero puede no conocer todos los
detalles del tipo. Por ejemplo, en el ejemplo de jQuery, arriba, el programador proporciona una expresión de función
como el segundo parámetro para el método ’get’. Durante el tipeo de esa expresión, las herramientas pueden suponer
que el tipo de expresión de la función es como se indica en la firma ’get’ y pueden proporcionar una plantilla que incluye
nombres y tipos de parámetros.
$.get("http://mysite.org/divContent",
function (data) {
$("div").text(data); // TypeScript infers data is a string
}
);
La tipificación contextual también es útil para escribir literales de objetos. A medida que el programador escribe el objeto
literal, el tipo contextual proporciona información que permite a las herramientas completar los nombres de los miembros
del objeto.
1.6 clases
La práctica de JavaScript tiene dos patrones de diseño muy comunes: el patrón de módulo y el patrón de clase. En
términos generales, el patrón del módulo usa cierres para ocultar nombres y encapsular datos privados, mientras que el
patrón de clase usa cadenas de prototipos para implementar muchas variaciones en los mecanismos de herencia
orientados a objetos. Las bibliotecas como ' prototype.js ' son típicas de esta práctica . Los espacios de nombres de
TypeScript son una formalización del patrón del módulo. (El término "patrón de módulo" es algo desafortunado ahora
que ECMAScript 2015 admite formalmente los módulos de una manera diferente de lo que prescribe el patrón de módulo.
Por esta razón, TypeScript utiliza el término "espacio de nombres" para su formalización del patrón de módulo).
Esta sección y la sección del espacio de nombres a continuación mostrarán cómo TypeScript emite JavaScript coherente e
idiomático al emitir código compatible con ECMAScript 3 o 5 para clases y espacios de nombres . El objetivo
de mecanografiado ' traducción s es emitir exactamente lo que un programador escriba la hora de implementar una clase
o espacio de nombres sin la ayuda de una herramienta. Esta sección también describirá cómo TypeScript infiere un tipo
para cada declaración de c lass. Nos ' Comenzaremos con una simple clase BankAccount.
class BankAccount {
balance = 0;
deposit(credit: number) {
this.balance += credit;
return this.balance;
}
}
interface BankAccount {
balance: number;
deposit(credit: number): number;
}
Si escribiéramos la declaración del tipo de función para la variable constructora ' BankAccount ' , tendría la siguiente
forma.
La firma de la función se prefija con la palabra clave ' nueva ' que indica que la ' BankAccount ' función de must ser
llamado como un constructor. Es posible que unas funciones de tipos de tener ambas firmas llamadas y constructor. Por
ejemplo, el tipo de la Fecha incorporado en JavaScript objeto incluye ambos tipos de firmas.
Si queremos comenzar nuestra cuenta bancaria con un saldo inicial, podemos agregar a la clase ' BankAccount ' una
declaración de constructor.
class BankAccount {
balance: number;
constructor(initially: number) {
this.balance = initially;
}
deposit(credit: number) {
this.balance += credit;
return this.balance;
}
}
class BankAccount {
constructor(public balance: number) {
}
deposit(credit: number) {
this.balance += credit;
return this.balance;
}
}
Las clases de TypeScript también pueden especificar miembros estáticos. Los miembros de la clase estática se convierten
en propiedades del constructor de la clase.
1.7 Tipos de enumeración
TypeScript permite a los programadores resumir un conjunto de constantes numéricas como un tipo de enum. El siguiente
ejemplo crea un tipo de enumeración para representar operadores en una aplicación de calculadora.
En este ejemplo, la función de cálculo registra el operador ' op ' usando una característica de tipos de enumeración:
mapeo inverso desde el valor de enumeración ( ' op ' ) a la cadena correspondiente a ese valor. Por ejemplo, la
declaración de ' Operador ' asigna automáticamente enteros, comenzando desde cero, a los miembros enumerados. La
Sección 9 describe cómo los programadores también pueden asignar explícitamente enteros a miembros de enumeración,
y pueden usar cualquier cadena para nombrar un miembro de enumeración.
Cuando las enumeraciones se declaran con la constante modifier, el compilador TypeScript emitirá para un miembro
enum una constante JavaScript correspondiente a ese miembro ' valor asignado s (anotado con un comentario). Esto
mejora el rendimiento en muchos motores de JavaScript.
switch (op) {
case Operator.ADD:
// execute add
break;
case Operator.DIV:
// execute div
break;
// ...
}
switch (op) {
case 0 /* Operator.ADD */:
// execute add
break;
case 1 /* Operator.DIV */:
// execute div
break;
// ...
}
Las implementaciones de JavaScript pueden usar estas constantes explícitas para generar código eficiente para esta
declaración de cambio, por ejemplo, creando una tabla de salto indexada por valor de caso.
Las interfaces de programación de JavaScript a menudo incluyen funciones cuyo comportamiento es discriminado por una
constante de cadena que se pasa a la función. El Modelo de Objetos del Documento hace un uso intensivo de este
patrón. Por ejemplo, la siguiente captura de pantalla muestra que
el método ' createElement ' del objeto ' document ' tiene múltiples firmas, algunas de las cuales identifican los tipos
devueltos cuando se pasan cadenas específicas al método.
El siguiente fragmento de código utiliza esta función. Debido a que se infiere que la variable ' span ' tiene el
tipo ' HTMLSpanElement ' , el código puede hacer referencia sin error estático a la propiedad ' isMultiline ' de ' span ' .
En la siguiente captura de pantalla, una herramienta de programación combina información de sobrecarga en parámetros
de cadena con tipeo contextual para inferir que el tipo de la variable ' e ' es ' MouseEvent ' y que, por lo tanto, ' e ' tiene
una propiedad ' clientX ' .
Para ilustrar esto, vamos a ' s echar un vistazo a parte de la interfaz de texto mecanografiado de la incorporada en el tipo
de matriz JavaScript. Puede encontrar esta interfaz en el archivo ' lib.d.ts ' que acompaña a una distribución TypeScript.
interface Array<T> {
reverse(): T[];
sort(compareFn?: (a: T, b: T) => number): T[];
// ...
}
Las definiciones de interfaz, como la anterior, pueden tener uno o más parámetros de tipo . En este caso,
la interfaz ' Array ' tiene un único parámetro, ' T ' , que define el tipo de elemento para la
matriz. El método ' inverso 'devuelve una matriz con el mismo tipo de elemento. El método de clasificación toma un
parámetro opcional, ' compareFn ' , cuyo tipo es una función que toma dos parámetros de tipo ' T ' y devuelve un
número. Finalmente, sort devuelve una matriz con el tipo de elemento ' T ' .
map<U>(func: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
El método de mapa, invocado en una matriz ' a ' con el tipo de elemento ' T ' , aplicará la función ' func ' a cada elemento
de ' a ' , obteniendo un valor de tipo ' U ' .
El compilador TypeScript a menudo puede inferir parámetros de métodos genéricos, lo que hace innecesario que el
programador los proporcione explícitamente. En el siguiente ejemplo, el compilador deduce que el parámetro' U ' del
método de mapa tiene el tipo ' cadena ' , porque la función pasada al mapa devuelve una cadena.
function numberToString(a: number[]) {
var stringArray = a.map(v => v.toString());
return stringArray;
}
En TypeScript, las clases también pueden tener parámetros de tipo. El siguiente código declara una clase que implementa
una lista enlazada de elementos del tipo ' T ' . Este código ilustra cómo los programadores pueden restringir
los parámetros de tipo para que se extiendan como tipo específico. En este caso, los elementos en la lista deben extender
el tipo ' NamedItem '. Esto permite que el programador implemente la función ' log ' , que registra el nombre del
elemento.
interface NamedItem {
name: string;
}
constructor(public item: T) {
}
insertAfter(item: T) {
var temp = this.next;
this.next = new List(item);
this.next.next = temp;
}
log() {
console.log(this.item.name);
}
// ...
}
En JavaScript, una forma muy común de imponer la encapsulación en tiempo de ejecución es utilizar el patrón del
módulo: encapsular campos privados y métodos utilizando variables de cierre. El patrón módulo es una forma natural
para proporcionar la estructura organizativa y las opciones de carga dinámica por sorteo ing un límite alrededor de un
software com ponente. El patrón del módulo también puede proporcionar la capacidad de introducir espacios de
nombres, evitando el uso del espacio de nombres global para la mayoría de los componentes de software.
(function(exports) {
var key = generateSecretKey();
function sendMessage(message) {
sendSecureMessage(message, key);
}
exports.sendMessage = sendMessage;
})(MessageModule);
Este ejemplo ilustra los dos elementos esenciales del patrón de módulo: un cierre de módulo y un objeto de módulo. El
cierre módulo es una función que encapsula el módulo de aplicaciones, en este caso la variable 'key' y la
función ' sendMessage ' . El objeto del módulo contiene las variables y funciones exportadas del módulo. Los módulos
simples pueden crear y devolver el objeto del módulo. El módulo anterior toma el objeto del módulo como
parámetro, ' exporta ' y agrega la propiedad ' sendMessage ' al objeto del módulo. Este enfoque de aumento simplifica la
carga dinámica de módulos y también admite la separación de código de módulo en múltiples archivos.
namespace M {
var s = "hello";
export function f() {
return s;
}
}
M.f();
M.s; // Error, s is not exported
En este ejemplo, la variable ' s ' es una característica privada del espacio de nombres , pero la función ' f ' se exporta
desde el espacio de nombres y se puede acceder al código fuera del espacio de nombres . Si tuviéramos que describir el
efecto del espacio de nombres ' M ' en términos de interfaces y variables, escribiríamos
interface M {
f(): string;
}
var M: M;
var M;
(function(M) {
var s = "hello";
function f() {
return s;
}
M.f = f;
})(M || (M = {}));
En este caso, el compilador supone que el objeto de espacio de nombres reside en la variable global ' M ' , que puede o
no haberse inicializado en el objeto de espacio de nombres deseado .
1.11 Módulos
TypeScript también admite módulos ECMAScript 2015 , que son archivos que contienen directivas
de importación y exportación de nivel superior . Para este tipo de módulo de la mecanografiado com piler puede emitir
tanto ECMAScript 2015 código compatible y hacia abajo a nivel de ECMAScript 3 o 5 código compatible para una variedad
de sistemas de módulo de carga, incluyendo CommonJS, asíncrono Módulo de Definición (AMD), y definición del módulo
universal (UMD )
2.1 Convenios de gramática
La gramática sintáctica agregada por el lenguaje TypeScript se especifica a lo largo de este documento utilizando
las convenciones existentes y los nombres de producción de la gramática ECMAScript. En lugares
donde TypeScript aumenta una producción gramatical existente, se nota así. Por ejemplo:
Declaration: ( Modified )
…
InterfaceDeclaration
TypeAliasDeclaration
EnumDeclaration
La anotación ' (Modified) ' indica que una producción gramatical existente está siendo reemplazada, y el ' ... '
hace referencia al contenido de la producción gramatical original.
Similar a la gramática ECMAScript, si la frase " [no hay LineTerminator aquí] " aparece en el lado derecho de una
producción de la gramática sintáctica, indica que la producción no coincide si se produce un LineTerminator en la
secuencia de entrada en el posición indicada
2.2 Nombres
Un núcleo propósito de la mecanografiado compilador es rastrear las entidades nombradas en un programa y validar que
se utilizan según su significado designado. Los nombres en TypeScript se pueden escribir de varias maneras, según el
contexto. Específicamente, un nombre se puede escribir como
un nombre identificador ,
un StringLiteral en un nombre de propiedad,
un NumericLiteral en un nombre de propiedad, o
un ComputedPropertyName que denota un símbolo bien conocido ( 2.2.3 ) .
Por lo general , los nombres se escriben para ajustarse a la producción del identificador , que es cualquier nombre
de identificador que no es una palabra reservada.
2.2.1 Palabras reservadas
Las siguientes palabras clave están reservadas y no se pueden usar como un Identificador:
Las siguientes palabras clave no se pueden utilizar como identificadores en el código de modo estricto, pero de lo
contrario no están restringidas:
Las siguientes palabras clave no se pueden usar como nombres de tipo definidos por el usuario, pero de lo contrario no
están restringidas :
Las siguientes palabras clave tienen un significado especial en ciertos contextos, pero son identificadores válidos:
PropertyName:
LiteralPropertyName
ComputedPropertyName
LiteralPropertyName:
IdentifierName
StringLiteral
NumericLiteral
ComputedPropertyName:
[ AssignmentExpression ]
Un nombre de propiedad puede ser cualquier identificador (incluida una palabra reservada), un literal de cadena, un
literal numérico o un nombre de propiedad calculado. Los literales de cadena se pueden usar para dar nombres de
propiedades que no son identificadores válidos, como nombres que contienen espacios en blanco. Los nombres de
propiedades literales numéricos son equivalentes a los nombres de propiedades literales de cadena con la representación
de cadena del literal numérico, tal como se define en la especificación ECMAScript.
[ Symbol . xxx ]
En un símbolo bien conocido, el identificador a la derecha del punto debe denotar una propiedad del símbolo de tipo
primitivo en el tipo de la variable global ’Símbolo’, o de lo contrario se produce un error .
A continuación se muestra un ejemplo de una interfaz que declara una propiedad con un nombre de símbolo conocido:
interface Iterable<T> {
[Symbol.iterator](): Iterator<T>;
}
TODO: Actualización para reflejar el tratamiento de nombres de propiedades calculados con expresiones literales .
2.3 Declaraciones
Las declaraciones introducen el nombre s en su espacio de declaración asociado s . Un nombre debe ser único en su
espacio de declaración y puede denotar un valor , un tipo , o un espacio de nombres , o alguna combinación de los
mismos . Efectivamente , un solo nombre puede tener hasta tres significados distintos . Por ejemplo:
var X: string; // Value named X
Un nombre que denota un valor tiene un tipo asociado (sección 3 ) y puede ser referenciado en
expresiones (sección 4.3 ) . Un nombre que denota un tipo puede usarse solo en una referencia de tipo o en el lado
derecho de un punto en una referencia de tipo ( 3.8.2 ) . Un nombre que denota un espacio de nombres se puede usar en
el lado izquierdo de un punto en una referencia de tipo.
En la primera línea, X hace referencia al tipo X porque ocurre en una posición de tipo. En la segunda línea, la primera X
hace referencia al espacio de nombres X porque aparece antes de un punto en un nombre de tipo, y la segunda X hace
referencia a la variable X porque aparece en una expresión.
A continuación se presentan algunos ejemplos de declaraciones que introducen múltiples significados para un nombre:
El espacio de nombres global, cada módulo y cada espacio de nombres declarado tiene un espacio de
declaración para sus entidades contenidas (ya sean locales o exportadas) .
E ACH módulo tiene una DeCLARA espacio ción de sus entidades exportados . Todas las declaraciones de
exportación en el módulo contribuyen a este espacio de declaración.
Cada espacio de nombres declarado tiene un espacio de declaración para sus entidades exportadas. Todas las
declaraciones de exportación en el espacio de nombres contribuyen a este espacio de declaración . Un espacio de
nombres del declarada espacio de declaración se comparte con otro espacio de nombres declarados s que tienen el
mismo contenedor raíz y el mismo cualificado na mí a partir de ese contenedor raíz .
Cada declaración de clase tiene un espacio de declaración para miembros de instancia y parámetros de tipo , y
un espacio de declaración para miembros estáticos.
Cada declaración de interfaz tiene un espacio de declaración para miembros y parámetros de tipo . Una
interfaz ' espacio de declaración s es compartida con otras interfaces que tienen el mismo contenedor raíz y el
mismo nombre calificado a partir de ese contenedor raíz .
Cada declaración de enumeración tiene un espacio de declaración para sus miembros de enumeración. Una
enumeración ' s espacio de declaración se comparte con otras enumeraciones que tienen el mismo contenedor
raíz y el nam cualificado misma a partir de ese correo contenedor raíz .
Cada declaración de alias de tipo tiene un espacio de declaración para sus parámetros de tipo.
Cada función -como declaración (incluyendo declaraciones de funciones, constructor declaraciones , miembro
de la función declaraciones , declaraciones miembro de descriptor de acceso , las expresiones de función, y las
funciones de dirección ) tiene un espacio de declaración de los locales y los parámetros de tipo. Este espacio de
declaración incluye declaraciones de parámetros, todas las declaraciones locales de var y funciones ,
y declaraciones locales let, const, class, interface, type alias y enum que ocurren inmediatamente con en el cuerpo
de la función y no se anidan en bloques.
Cada bloque de declaración tiene un espacio de declaración para las declaraciones locales let, const, class,
interface, ty pe alias y enum que ocurren inmediatamente dentro de ese bloque.
Cada objeto literal tiene un espacio de declaración para sus propiedades.
Cada tipo de objeto literal tiene un espacio de declaración para sus miembros.
Las declaraciones de nivel superior en un archivo fuente sin declaraciones de importación o exportación de nivel
superior pertenecen al espacio de nombres global . Las declaraciones de nivel superior en un archivo fuente con una o
más declaraciones de importación o exportación de nivel superior pertenecen al módulo representado por ese archivo
fuente.
Las instancias y los miembros estáticos en una clase están en espacios de declaración separados . Por lo tanto, se permite
lo siguiente:
2,4 Alcances
El alcance de un nombre es la región del texto del programa dentro del cual es posible hacer referencia a la entidad
declarada por ese nombre sin calificación del nombre. El alcance de un nombre depende del contexto en el que se declara
el nombre. Los contextos se enumeran a continuación en orden de más externo a más interno:
Los ámbitos pueden superponerse, por ejemplo, mediante el anidamiento de espacios de nombres y funciones. Cuando
los alcances de dos nombre s solapamiento, el nombre con el más interno declaración tiene prioridad y el acceso
al exterior el nombre i s bien no es posible o sólo es posible por la calificación .
Cuando un identificador se resuelve como una Expresión primaria (sección 4.3 ), solo se consideran los nombres en el
ámbito con un significado de valor y se ignoran otros nombres.
Tenga en cuenta que los miembros de la clase y la interfaz nunca están directamente dentro del alcance; solo se puede
acceder aplicando el operador de punto ( ' . ' ) A una clase o instancia de interfaz . Esto incluye también miembros de la
instancia actual en una función constructor o miembro, que se accede mediante la aplicación del operador de punto
a este .
Como implican las reglas anteriores, las entidades declaradas localmente en un espacio de nombres tienen un alcance
más cercano que las entidades exportadas declaradas en otras declaraciones de espacio de nombres para el
mismo espacio de nombres . Por ejemplo:
var x = 1 ;
espacio de nombres M { export var x = 2 ; console.log (x); // 2 } espacio de nombres M {
console.log (x); // 2 } espacio de nombres M { var x = 3 ; console.log (x); // 3 }
1
3 Tipos
TypeScript agrega tipos estáticos opcionales a JavaScript. Tipos se utilizan para colocar restricción estática t s en entidades
de programas tales como func iones, variables y propiedades de modo que los compiladores y herramientas de desarrollo
pueden ofrecer una mejor verificación y asistencia durante el software de desarrollo . Mecanografiado ' s estática en
tiempo de compilación tipo sys tem modelos de cerca la dinámica del sistema de tipo de tiempo de ejecución de
JavaScript, lo que permite a los programadores para expresar con precisión las relaciones de tipo que se esperan de existir
cuando sus programas de gestión y hacer que esos supuestos previamente validados por
el mecanografiado compilador . Letra de imprenta ' análisis tipo s se produce completamente en tiempo de compilación y
añade ninguna sobrecarga de tiempo de ejecución para la ejecución del programa.
Todos los tipos en TypeScript son subtipos de un solo tipo superior llamado Cualquier tipo. La cualquier refere palabra
clave NCES este tipo. Cualquier tipo es el único que puede representar cualquier valor de JavaScript sin
restricciones . Todos los demás tipos se clasifican como tipos primitivos , tipos de objetos , tipos de unión , tipos de
intersección , o parámetros de tipo . Estos tipos introducen varias restricciones estáticas en sus valores.
Los tipos primitivos son el número, B ool ean, String, Símbolo, Vacío, Null, y U ndefined tipos junto con definidos por el
usuario tipos enum . El número , booleano , cadena , símbolo , y el vacío de palabras clave ref s rencia el número,
booleano, cadena , símbolo, y anular los tipos primitivos , respectivamente . El tipo de vacío existe únicamente para indicar
la ausencia de un valor, como en una función sin valor de retorno. No se posib le para hacer referencia de forma explícita
el Null y U ndefined tipos: sólo los valores de esos tipos se puede hacer referencia , usin g los nulos y no
definidos Lite RAL .
Los tipos de objeto son todos los tipos de clase, interfaz, matriz, tupla, función y constructor . Los tipos de clase e interfaz
se introducen a través de declaraciones de clase e interfaz y se hace referencia por el nombre que se les da en sus
declaraciones. Los tipos de clase e interfaz pueden ser tipos genéricos que tienen uno o más parámetros de tipo.
Los tipos de unión representan valores que tienen uno de varios tipos, y los tipos de intersección representan valores que
tienen simultáneamente más de un tipo .
Las declaraciones de clases, propiedades, funciones, variables y otras entidades del lenguaje asocian tipos con esas
entidades. El mecanismo por el cual se forma un tipo y se asocia con una entidad de lenguaje depende del tipo particular
de entidad. Por ejemplo, un espacio de nombres de declaración asocia el espacio de nombres con una n anónimo tipo
que contiene un conjunto de propiedades que corresponden a las variables exportadas y funciones en el espacio de
nombres , y una declaración de función asocia la función con un anónimo n tipo que contiene una firma de llamada
correspondiente a los parámetros y tipo de retorno de la función. Los tipos pueden asociarse con variables a través
de anotaciones de tipo explícitas , como
var x: número ;
var x = 1 ;
que infiere que el tipo de ' x ' será el tipo primitivo Numérico porque ese es el tipo del valor utilizado para inicializar ' x ' .
La cualquier refere palabra clave NCES la Cualquier tipo. En general, en lugares donde no se proporciona un tipo
explícitamente y TypeScript no puede inferir uno , se asume el tipo Any .
Any t ype es un supertipo de todos los tipos y se puede asignar a todos los tipos.
Algunos ejemplos:
3.2 Tipos primitivos
Los primitivos tipos son el Número, B ool ean , S Tring , Símbolo, Vacío, Null, y U ndefined tipos y todos los tipos enum
definidos por el usuario.
3.2.1 El N umber T ipo
El tipo primitivo Número corresponde al tipo primitivo JavaScript con un nombre similar y representa valores de coma
flotante IEEE 754 de formato de doble precisión de 64 bits.
El número clave palabra hace referencia a la N umber primitivo tipo y n literales Umeric puede ser usado para escribir
valores del número primitivo tipo.
Para fines de determinar las relaciones de tipo (sección 3.11 ) y acceder a las propiedades (sección 4.13 ) ,
el tipo primitivo Número se comporta como un tipo de objeto con los mismos vínculos apropiados que el tipo de interfaz
global ' Número ' .
Algunos ejemplos:
3.2.2 The Bool ean T ype
El tipo primitivo booleano corresponde al tipo primitivo JavaScript con un nombre similar y representa valores lógicos que
son verdaderos o falsos.
Para determinar las relaciones de tipo (sección 3.11 ) y acceder a las propiedades (sección 4.13 ) ,
el tipo primitivo booleano se comporta como un tipo de objeto con las mismas propiedades que el tipo de interfaz
global ' Boolean ' .
Algunos ejemplos:
Para determinar las relaciones de tipo (sección 3.11 ) y acceder a las propiedades (sección 4.13 ) , el tipo primitivo String
se comporta como un tipo de objeto con las mismas propiedades que el tipo de interfaz global ' String ' .
Algunos ejemplos:
Algunos ejemplos:
Los únicos valores posibles para el tipo Void son nulos e indefinidos . El tipo Void es un subtipo del tipo Any y un
supertipo del tipo s nulo e indefinido , pero de lo contrario, Void no está relacionado con todos los demás tipos.
NOTA: Podríamos considerar no permitir declarar variables de tipo Void, ya que no tienen ningún propósito útil . Sin
embargo, dado que Void está permitido como argumento de tipo para un tipo o función genérico , no es posible rechazar
propiedades o parámetros de Void .
El literal nulo hace referencia al único valor del tipo nulo. No es posible hacer referencia directa al tipo nulo en sí.
Algunos ejemplos:
var n: número = nulo ; // Las primitivas pueden ser nulas var x = null ; // Igual que x: any
= null var e: Null; // Error, lata ' t referencia de tipo Null
T él indefinido literal denota el valor dado a todas las variables sin inicializar y es el único valor del tipo definido. No es
posible hacer referencia directa al tipo Indefinido en sí.
El tipo indefinido es un subtipo de todos los tipos. Esto significa que lo indefinido se considera un valor válido
para todos los tipos primitivos , tipos de objeto , tipos de unión, tipos de intersección y parámetros de tipo .
Algunos ejemplos:
3.2.8 Tipos de enumeración
Los tipos de enumeración son distintos subtipos definidos por el usuario del tipo primitivo Número. Los tipos de
enumeración se declaran mediante declaraciones de enumeración (sección 9.1 ) y se hace referencia mediante referencias
de tipo (sección 3.8.2 ).
Los tipos de enumeración se pueden asignar al tipo primitivo Número y viceversa, pero los diferentes tipos de
enumeración no se pueden asignar entre sí.
Todos los tipos literales de cadena son subtipos del tipo primitivo de cadena.
TODO: Actualización para reflejar el soporte ampliado para los tipos literales de cadena .
3,3 Tipos de objeto
Los tipos de objetos se componen de propiedades, firmas de llamada, firmas de construcción y firmas de índice ,
denominadas colectivamente miembros.
Las referencias de tipo de clase e interfaz, los tipos de matriz , los tipos de tupla, los tipos de funciones y los tipos de
constructor se clasifican como tipos de objeto. Múltiples construcciones en el lenguaje TypeScript crean tipos de objetos ,
que incluyen:
3.3.2 Tipos de matriz
Los tipos de matriz representan matrices de JavaScript con un tipo de elemento común. Los tipos de matriz son
referencias de tipo con nombre creadas a partir del tipo de interfaz genérico ' Array ' en el espacio de nombres global con
el tipo de elemento de matriz como argumento de tipo . Los literales de tipo matriz (sección 3.8.4 ) proporcionan una
notación abreviada para crear tales referencias.
La declaración de la interfaz ' Array ' incluye una propiedad ' length ' y una firma de índice numérico para el tipo de
elemento, junto con otros miembros:
interfaz Array <T> {
longitud: número ;
[x: número ]: T; // Otros miembros }
Los literales de matriz (sección 4.6 ) pueden usarse para crear valores de tipos de matriz. Por ejemplo
var a: cadena [] = [ " hola " , " mundo " ];
3.3.3 Tipos de tuplas
Los tipos de tupla representan matrices de JavaScript con tipos de elementos individualmente rastreados . Los tipos de
tupla se escriben usando literales de tipo tupla (sección 3.8.5 ). Un tipo tupla combinan s un conjunto de propiedades
numéricamente nombradas con los miembros de un tipo de matriz . Específicamente, un tipo de tupla
combina el conjunto de propiedades
{
0: T0;
1: T1;
...
n: Tn;
}
con los miembros de un tipo de matriz cuyo tipo de elemento es el tipo de unión (sección 3.4 ) de los tipos de elementos
de tupla.
Los tipos de tuplas con nombre se pueden crear declarando interfaces que se derivan de la matriz <T> e introducen
propiedades con nombre numérico. Por ejemplo:
Un tipo se dice que es una tupla tipo -como si tiene una propiedad con el nombre de '0'.
3.3.4 Tipos de funciones
Se dice que un tipo de objeto que contiene una o más firmas de llamada es un tipo de función . Los tipos de función se
pueden escribir utilizando literales de tipo de función (sección 3.8.8 ) o incluyendo firmas de llamada en literales de tipo
de objeto.
3.3.5 Tipos de constructor
Se dice que un tipo de objeto que contiene una o más firmas de construcción es un tipo de constructor . Los tipos de
constructor se pueden escribir utilizando literales de tipo de constructor (sección 3.8.9 ) o incluyendo firmas de
construcción en literales de tipo de objeto.
3.3.6 Miembros
Cada tipo de objeto está compuesto de cero o más de los siguientes tipos de miembros:
Properties , que definen los nombres de un d tipos de las propiedades de objeto s del tipo dado. Los nombres de
propiedad son únicos dentro de su tipo.
Llame a las firmas , las cuales definen las posibles listas de parámetros y volver tipo s asociados con la
aplicación operación de llamada s a objetar s del tipo dado.
Construir firmas , que definen los posibles listas de parámetros y volver tipo s asociada con la aplicación de
t él nuevo operador de oponerse s del tipo dado.
Firmas de índice , que definen restricciones de tipo para propiedades en el tipo dado. Un tipo de objeto puede
tener como máximo una firma de índice de cadena y una firma de índice numérico.
Las firmas de llamada y construcción pueden ser especializadas (sección 3.9.2.4 ) al incluir parámetros con tipos literales
de cadena. Las firmas especializadas se utilizan para expresar patrones donde los valores de cadena específicos para
algunos parámetros hacen que los tipos de otros parámetros o el resultado de la función se especialicen aún más.
3.4 Tipos de unión
Los tipos de unión representan valores que pueden tener una de varias representaciones distintas . Un valor de una unión
tipo A | B es un valor que es ya sea de tipo A o tipo B . Los tipos de unión se escriben usando literales de tipo de unión
(sección 3.8.6 ).
Un tipo de unión abarca un conjunto ordenado de tipos constituyentes . Si bien es generalmente cierto que A | B es
equivalente a B | A , el orden de los tipos constituyentes puede ser importante al determinar la llamada y construir firmas
del tipo de unión.
Del mismo modo, los tipos de unión tienen las siguientes relaciones de asignabilidad:
El || y los operadores condicionales (sección 4.19.7 y 4.20 ) pueden producir valores de tipos de unión, y los literales de
matriz (sección 4.6 ) pueden producir valores de matriz que tienen tipos de unión como sus tipos de elementos.
Los protectores de tipo (sección 4.24 ) pueden usarse para reducir un tipo de unión a un tipo más específico. En particular,
los protectores de tipo son útiles para limitar los valores de tipo de unión a valores de tipo no sindicalizados.
En el ejemplo
var x: cadena | número ; prueba
var : boolean ;
x = "hola" ; // Ok
x = 42 ; // Ok
x = prueba; // Error, booleano no asignable
x = prueba? 5 : "cinco" ; // Ok
x = prueba? 0 : falso ; // Error, número | booleano no culo ignable
es posible asignar a 'x' un valor de tipo cadena , número o la cadena tipo unión | número , pero no cualquier otro
tipo. Para acceder a un valor en 'x', se puede usar un protector de tipo para reducir primero el tipo de 'x'
a cadena o número :
interfaz A {
a: cadena ;
b: número ;
}
interfaz B {
a: número ;
b: número ;
c: número ;
}
var x: A | SEGUNDO;
var a = xa; // a tiene tipo cadena | número
var b = xb; // b tiene el número de tipo
var c = xc; // Error, no hay propiedad c en tipo de unión
Tenga en cuenta que 'xa' tiene un tipo de unión porque el tipo de 'a' es diferente en 'A' y 'B', mientras que 'xb'
simplemente tiene un número de tipo porque ese es el tipo de 'b' en 'A' y 'SEGUNDO'. También tenga en cuenta que no
existe la propiedad 'xc' porque solo 'B ' tiene una propiedad 'c'.
Cuando se usa como un tipo contextual (sección 4.23 ), un tipo de unión tiene aquellos miembros que están presentes en
cualquiera de sus tipos constituyentes, con tipos que son uniones de los miembros respectivos en los tipos
constituyentes. Específicamente, un tipo de unión utilizado como tipo contextual tiene los miembros aparentes definidos
en la sección 3.11.1 , excepto que un miembro particular solo necesita estar presente en uno o más tipos constituyentes
en lugar de todos los tipos constituyentes.
3.5 Tipos de intersección
Los tipos de intersección representan valores que simultáneamente tienen múltiples tipos. Un valor de un tipo de
intersección A y B es un valor que es tanto de tipo A y tipo B . Los tipos de intersección se escriben usando literales de
tipo intersección (sección 3.8.7 ).
Un tipo de intersección abarca un conjunto ordenado de tipos constituyentes. Si bien es generalmente cierto que A y B es
equivalente a B y A , el orden de los tipos constituyentes puede ser importante al determinar la llamada y construir firmas
del tipo de intersección.
Un tipo de intersección que se puede asignar a un tipo T , si cualquier tipo en que se puede asignar a T .
Un tipo T es asignable a un tipo de intersección I si T es asignable a cada tipo en I .
interfaz A {a: número }
interfaz B {b: número }
var ab : A y B = {a: 1 , b: 1 };
var a: A = ab; // A y B asignables a A var b: B = ab; // A y B asignables a B
interfaz X {p: A}
interfaz Y {p: B}
var xy: X e Y = {p: ab }; // X e Y tiene la propiedad p de tipo A y B
escriba F1 = (a : cadena , b: cadena ) => vacío ;
tipo F2 = (a : número , b: número ) => vacío ;
var f: F1 y F2 = (a: cadena | número , b: cadena | número ) => {};
f ( "hola" , "mundo" ); // Ok f ( 1 , 2 ); // Ok f ( 1 , "prueba" ); // Error
Los operadores de tipo unión e intersección se pueden aplicar a los parámetros de tipo. Esta capacidad se puede usar, por
ejemplo, para modelar funciones que combinan objetos:
función extender <T, U> (primero: T, segundo: U): T & U { // Extender primero con propiedades de
segundo }
Es posible crear tipos de intersección para los cuales no son posibles valores distintos de nulo o indefinido. Por ejemplo,
las intersecciones de tipos primitivos como cadena y número se incluyen en esta categoría.
3.6 Parámetros de tipo
Un parámetro de tipo representa un tipo real al que está vinculado el parámetro en una referencia de tipo genérico o una
llamada de función genérica. Los parámetros de tipo tienen restricciones que establecen límites superiores para sus
argumentos de tipo reales.
Dado que un parámetro de tipo representa una multitud de argumentos de tipo diferentes, los parámetros de tipo tienen
ciertas restricciones en comparación con otros tipos. En particular, un parámetro de tipo no puede usarse como una clase
base o interfaz.
TypeParameters:
< TypeParameterList >
TypeParameterList:
TypeParameter
TypeParameterList , TypeParameter
TypeParameter:
Binding Identifier Restricción
opt
Restricción:
extiende el tipo
Los nombres de los parámetros de tipo deben ser únicos. Se produce un error en tiempo de compilación si dos o más
parámetros de tipo en la misma TypeParameterList tienen el mismo nombre.
El alcance de un parámetro de tipo se extiende sobre toda la declaración con la que está asociada la lista de parámetros
de tipo, con la excepción de las declaraciones de miembros estáticos en las clases.
Un parámetro de tipo puede tener una restricción de parámetro de tipo asociada que establece un límite superior para
los argumentos de tipo . Se puede hacer referencia a los parámetros de tipo en las restricciones de parámetros de tipo
dentro de la misma lista de parámetros de tipo, incluidas las declaraciones de restricciones que se producen a la izquierda
del parámetro de tipo.
Si T tiene ninguna restricción declarada, T ' restricción de base s es el tipo de objeto vacío {} .
Si T ' restricción declarada s es un parámetro de tipo, T ' restricción de base de s es la del tipo de parámetro.
De lo contrario, T ' restricción de base de s es T ' restricción declarada s.
En el ejemplo
la restricción base de 'T' es el tipo de objeto vacío y la restricción base de 'U' y 'V' es 'Función' .
Para determinar las relaciones de tipo (sección 3.11 ), los parámetros de tipo parecen ser subtipos de su restricción
base. Del mismo modo, en los accesos a propiedades (sección 4.13 ), nuevas operaciones (sección 4.14 ) y llamadas a
funciones (sección 4.15 ), los parámetros de tipo parecen tener los miembros de su restricción base, pero no otros
miembros.
Es un error que un parámetro de tipo sea directa o indirectamente una restricción para sí mismo. Por ejemplo, las dos
declaraciones siguientes no son válidas:
interfaz A <T extiende T> {}
interfaz B <T extiende U, U extiende T> {}
TypeArguments:
< TypeArgumentList >
TypeArgumentList:
TypeArgument
TypeArgumentList , TypeArgument
Tipo Argumento:
Tipo
Los argumentos de tipo corresponden uno a uno con los parámetros de tipo del tipo genérico o función a la que se hace
referencia. Se requiere una lista de argumentos de tipo para especificar exactamente un argumento de tipo para cada
parámetro de tipo correspondiente, y cada argumento de tipo para un parámetro de tipo restringido es necesario
para satisfacer la restricción de ese parámetro de tipo. Un argumento de tipo satisface una restricción de parámetro de
tipo si el argumento de tipo es asignable a (sección 3.11.4 ) el tipo de restricción una vez que los argumentos de tipo son
sustituidos por parámetros de tipo.
Dada la declaración
interfaz G <T , U extiende Función > {}
una referencia de tipo de la forma ' G <A, B > ' no establece requisitos en ' A ' pero requiere que ' B ' sea asignable
a ' Función ' .
El proceso de sustitución de argumentos de tipo por parámetros de tipo en un tipo genérico o firma genérica se conoce
como instanciación del tipo genérico o firma. La creación de instancias de un tipo genérico o firma puede fallar si los
argumentos de tipo suministrados no satisfacen las limitaciones de sus parámetros de tipo correspondientes.
3.6.3 Esto- tipos
Cada clase e interfaz tiene este tipo que representa el tipo real de instancias de la clase o interfaz dentro de la declaración
de la clase o interfaz . Se hace referencia a este tipo utilizando la palabra clave this en una posición de tipo. Dentro de
los métodos de instancia y los constructores de una clase, el tipo de expresión this (sección 4.2 ) es el tipo this de la
clase.
clase A {
foo () {
devuelve esto;
}
}
la clase B extiende A {
bar () { devuelve esto; } }
dejar b: B;
let x = b.foo (). bar (); // El patrón fluido funciona, el tipo de x es B
En la declaración de b más arriba, el tipo de referencia B es en sí mismo pasa como un argumento de tipo para este tipo
de B . Por lo tanto, la r eferen tipo ced es una instanciación de la clase B , donde todas las ocurrencias del
tipo este se reemplazan con B , y por esa razón el foo método de B devuelve realmente B (en contraposición a A ).
El tipo de este de una clase o tipo de interfaz dada C implícitamente tiene una restricción que consiste en una referencia
de tipo de C con C propios parámetros de tipo 's pasados como argumentos de tipo y con esa referencia de tipo pasado
como el tipo de argumento para el este de tipo .
Las declaraciones de interfaz solo introducen tipos con nombre, mientras que las declaraciones de clase introducen tipos
con nombre y funciones de constructor que crean instancias de implementaciones de esos tipos con nombre . Los tipos
con nombre introducidas por las declaraciones de clases e interfaces tienen sólo pequeñas diferencias de clase
( ES puede ' t declarar miembros opcionales e interfaz s puede ' t declarar privadas o protegidas miembros) y se
encuentran en la mayoría de los contextos intercambiables. En particular, las declaraciones de clase con
solo miembros públicos introducen tipos con nombre que funcionan exactamente como los creados por las declaraciones
de interfaz.
Los tipos con nombre se referencian a través de referencias de tipo (sección 3.8.2 ) que especifican un nombre de tipo y,
si corresponde, los argumentos de tipo que se sustituirán por los parámetros de tipo del tipo con nombre.
Los tipos con nombre no son técnicamente tipos, solo lo son las referencias a tipos con nombre. Esta distinción es
particularmente e vident con tipos genéricos: tipos genéricos son " plantillas " de la que
múltiples reales tipos pueden ser creadas por escrito referencias tipo que s upply escriben argumentos para sustituir en
lugar del tipo genérico de ' parámetros de tipo s. Este proceso de sustitución se conoce como instanciar un tipo
genérico . O ólo una vez al tipo genérico se instancia Qué denotar un tipo real.
TypeScri pt tiene un sistema de tipo estructural y , por lo tanto, una instancia de un tipo genérico es indistinguible de una
expansión escrita manualmente equivalente . Por ejemplo, dada la declaración
la referencia de tipo
{primero: cadena ; segundo: entidad; }
3.8 Especificando tipos
Los tipos se especifican haciendo referencia a su palabra clave o nombre, o escribiendo literales de tipo de objeto ,
literales de tipo de matriz, literales de tipo de tupla , literales de tipo de función , literales de tipo de constructor o
consultas de tipo .
Tipo:
UnionOrIntersectionOr PrimaryType
FunctionType
ConstructorType
UnionOrIntersectionOrPrimaryType:
UnionType
IntersectionOrPrimaryType
IntersectionOrPrimaryType:
IntersectionType
PrimaryType
Tipo primario :
ParenthesizedType
PredefinedType
TypeReference
ObjectType
ArrayType
TupleType
TypeQuery
ThisType
ParenthesizedType:
( Tipo )
( cadena | número ) []
((x: cadena ) => cadena ) | ( (x: número ) => número )
(A | B) y (C | D)
3.8.1 Tipos predefinidos
Las palabras clave any , number , boolean , string , symbol y void hacen referencia al tipo Any y
los tipos primitivos Number, Boolean, String , Symbol y Void respectivamente.
PredefinedType:
cualquier
número
boolean
string
symbol
void
Las palabras clave de tipo predefinidas se guardan y no se pueden usar como nombres de tipos definidos por el usuario .
3.8.2 Referencias de tipo
Una referencia de tipo hace referencia a un tipo con nombre o parámetro de tipo a través de su nombre y, en el caso de
un tipo genérico, proporciona una lista de argumentos de tipo.
TypeReference:
TypeName [no LineTerminator aquí] TypeArguments
opt
NamespaceName :
Identificador de referencia
NamespaceName . I dentificador Referencia
Una TypeReference consta de un TypeName que hace referencia a un tipo o parámetro de tipo con nombre. Una
referencia a un tipo genérico debe ir seguida de una lista de argumentos de tipo (sección 3.6.2 ).
Un TypeName es un identificador único o una secuencia de identificadores separados por puntos. En un nombre de tipo,
todos los identificadores, excepto el último, se refieren a espacios de nombres y el último identificador se refiere a un tipo
con nombre.
interfaz A { a: cadena ; }
la interfaz B extiende A { b: cadena ; }
la interfaz C extiende B {c: cadena ; }
interfaz G <T, U se extiende B > { x: T; Yu; }
var v1: G <A, C >; // Ok var v2: G <{a: string }, C>; // Ok, equivalente a G <A, C> var v3: G < A,
A >; // Error, un argumento no válido para U var v4: G <G <A, B >, C >; // Ok var v 5:
G < cualquiera , cualquiera >; // Ok var v6: G < cualquiera >; // Error, número
incorrecto de argumentos var v 7 : G ; // Error, sin argumentos
Un argumento de tipo es simplemente un Tipo y puede ser en sí mismo una referencia de tipo a un tipo genérico, como
lo demuestra ' v4 ' en el ejemplo anterior.
Como se describe en la sección 3.7 , una referencia de tipo a un tipo genérico G designa un tipo en el que todas las
apariciones de los parámetros de tipo de G se han reemplazado con los argumentos de tipo reales suministrados en la
referencia de tipo. Por ejemplo, la declaración de ' v1 ' anterior es equivalente a:
var v1: {
x: {a: cadena ; }
y: { a: cadena ; b: cadena ; c: cadena }; };
TypeBody:
TypeMemberList ; TypeMemberList ,
opt opt
TypeMemberList:
TypeMember
TypeMemberList ; TypeMember TypeMemberList , TypeMember
TypeMember:
PropertySignature
CallSignature
ConstructSignature
IndexSignature
MethodSignature
Los miembros de un tipo de objeto literal se especifican como una combinación de firmas de propiedad, llamada,
construcción, índice y método. Los miembros del tipo de objeto se describen en la sección 3.9 .
3.8.4 Array Type Literals
Un literal de tipo de matriz se escribe como un tipo de elemento seguido de un corchete abierto y cerrado.
ArrayType: Tipo
primario [sin LineTerminator aquí] [ ]
Un literal de tipo de matriz hace referencia a un tipo de matriz (sección 3.3.2 ) con el tipo de elemento dado. Un literal
de tipo de matriz es simplemente una notación abreviada para una referencia al tipo de interfaz genérico ' Array ' en
el espacio de nombres global con el tipo de elemento como argumento de tipo .
Cuando los tipos de unión, intersección, función o constructor se utilizan como tipos de elementos de matriz, deben
encerrarse entre paréntesis. Por ejemplo:
( cadena | número ) []
(() => cadena )) []
Alternativamente , el tipo de matriz s se puede escribir usando la notación ' Array <T> ' . Por ejemplo, los tipos anteriores
son equivalentes a
Array < cadena | número >
matriz <() => cadena >
3.8.5 Tuple Type Literals
Un literal de tipo tupla se escribe como una secuencia de tipos de elementos, separados por comas y encerrados entre
corchetes.
TupleType:
[ TupleElementTypes ]
TupleElementTypes:
TupleElementType
TupleElementTypes , TupleElementType
TupleElementType:
Type
UnionType:
Union OrIntersectionOrPrimary Type | IntersectionOrP rimaryType
3.8.8 Tipo de función Literales
Un literal de tipo de función especifica los parámetros de tipo, los parámetros regulares y el tipo de retorno de una firma
de llamada.
FunctionType:
TypeParameters ( ParameterList ) => Tipo
opt opt
Un literal de tipo de función es una forma abreviada de un tipo de objeto que contiene una sola firma de
llamada. Específicamente, un tipo de función literal de la forma
Tenga en cuenta que los tipos de función con múltiples firmas de llamada o construcción no pueden escribirse como
literales de tipo de función, sino que deben escribirse como literales de tipo de objeto.
3.8.9 Constructor Tipo Literales
Un literal de tipo de constructor especifica los parámetros de tipo, los parámetros regulares y el tipo de retorno de una
firma de construcción.
ConstructorType:
new TypeParameters ( ParameterList ) => Tipo
opt opt
Un literal de tipo de constructor es la abreviatura de un tipo de objeto que contiene una única firma de
construcción. Específicamente, un tipo de constructor literal de la forma
Tenga en cuenta que los tipos de constructor con múltiples firmas de construcción no pueden escribirse como literales de
tipo de constructor, sino que deben escribirse como literales de tipo de objeto.
3.8.10 Consultas de tipo
Una consulta de tipo obtiene el tipo de una expresión.
TypeQuery:
typeof TypeQueryExpression
TypeQueryExpression:
Identificador de referencia
TypeQueryExpression . IdentifierName
Una consulta de tipo consiste en la palabra clave typeof seguida de una expresión. La expresión está restringida a un
solo identificador o una secuencia de identificadores separados por puntos. La expresión se procesa como una expresión
de identificación (sección 4.3 ) o expresión de acceso a la propiedad (sección 4.13 ) , cuyo tipo ampliado (sección 3.12 )
se convierte en el resultado. Al igual que otras construcciones de escritura estática , las consultas de escritura se borran
del código JavaScript generado y no agregan sobrecarga en tiempo de ejecución.
Las consultas de tipos son útiles para capturar tipos anónimos generados por diversas construcciones, como literales de
objetos, declaraciones de funciones y declaraciones de espacios de nombres . Por ejemplo:
Si una declaración incluye una anotación de tipo que hace referencia a la entidad que se declara a través de una ruta
circular de consultas de tipo o referencias de tipo que contienen consultas de tipo , el tipo resultante es Cualquier
tipo. Por ejemplo , a todas las siguientes variables se les asigna el tipo Cualquiera:
var c: typeof c;
var d: typeof e;
var e: typeof d;
var f: Matriz < typeof f>;
Aquí, ' g ' y ' gx ' tienen el mismo tipo recursivo, y del mismo modo ' h ' y ' h () ' tienen el mismo tipo recursivo.
ThisType:
this
El significado de una ThisType depende el más cercano de
cerramiento FunctionDeclaration , FunctionExpression , PropertyDefinition , ClassElement o TypeMember , conocida como
la declaración de la raíz de la ThisType , de la siguiente manera:
Cuando la declaración raíz es un miembro de la instancia o un constructor de una clase , ThisType hace referencia
al this-type de esa clase.
Cuando la declaración de la raíz es un miembro de un tipo de interfaz, la ThisType hace referencia al tipo este de
esa interfaz.
De lo contrario, el ThisType es un error.
Tenga en cuenta que para evitar ambigüedades no es posible hacer referencia a este tipo de una clase o interfaz en un
tipo de objeto anidado literal. En el ejemplo
interfaz ListItem {
getHead (): esto ;
getTail (): esto ;
getHeadAndTail (): {head: this , tail: this }; // Error
}
las referencias de este en la última línea son erróneas porque sus declaraciones raíz no son miembros de una clase o
interfaz. La forma recomendada para hacer referencia a la presente de tipo de una clase externa o la interfaz en un tipo de
objeto literal es declarar un tipo genérico intermedio y pasar este como un argumento de tipo. Por ejemplo:
3.9 Especificando miembros
Los miembros de un tipo n objeto literal (sección 3.8.3 ) se especifican como una combinación de la propiedad, llamar,
construir, índice , y método de firmas.
3.9.1 Firmas de propiedad
Una firma de propiedad declara el nombre y el tipo de un miembro de la propiedad.
PropertySignature:
PropertyName ? Tipo Anotación
opt opt
TypeAnnotation
:: Type
El PropertyName ( 2.2.2 ) de una firma de propiedad debe ser único dentro de su tipo contenedor y debe denotar un
símbolo bien conocido si es un nombre de propiedad calculado ( 2.2.3 ). Si el nombre de la propiedad va seguido de un
signo de interrogación, la propiedad es opcional. De lo contrario, se requiere la propiedad.
3.9.2 Firmas de llamadas
Una firma llamada define los parámetros de tipo, lista de parámetros , y tipo de retorno asociados con la aplicación de
una operación de llamada (sección 4.15 ) a una instancia del tipo que contiene. Un tipo puede sobrecargar las
operaciones de llamadas definiendo múltiples firmas de llamadas diferentes.
CallSignature:
TypeParameters ( ParameterList ) TypeAnnotation
opt opt opt
Una firma de llamada que incluye TypeParameters (sección 3.6.1 ) se denomina firma de llamada genérica . Por el
contrario, una firma de llamada sin TypeParameters se denomina firma de llamada no genérica.
Además de ser miembros de literales de tipo de objeto, las firmas de llamada se producen en firmas
de método ( sección 3.9.5 ), expresiones de función ( sección 4.10 ) y declaraciones de función ( sección 6.1 ).
Se dice que un tipo de objeto que contiene firmas de llamada es un tipo de función .
3.9.2.1 Parámetros de tipo
Los parámetros de tipo (sección 3.6.1 ) en las firmas de llamada proporcionan un mecanismo para expresar las relaciones
de los parámetros y los tipos de retorno en las operaciones de llamada. Por ejemplo, una firma podría introducir un
parámetro de tipo y utilizarlo como tanto un tipo de parámetro y un tipo de retorno, en efecto que describe una función
que la de regreso s un valor o f del mismo tipo que su argumento.
T ipo parámetros pueden ser referenciados en los tipos de parámetros y el tipo de retorno anotaciones , pero no en las
limitaciones de los parámetros de tipo, de la firma llamada en la que se introducen .
Los argumentos de tipo (sección 3.6.2 ) para los parámetros de tipo de firma de llamada pueden especificarse
explícitamente en una operación de llamada o, cuando sea posible, inferirse (sección 4.15.2 ) de los tipos de argumentos
regulares en la llamada. Una instancia de una firma de llamada genérica para un conjunto particular de argumentos de
tipo es la firma de llamada formada al reemplazar cada parámetro de tipo con su argumento de tipo correspondiente.
Una función que toma un argumento de cualquier tipo, devolviendo un valor del mismo tipo:
Una función que toma dos valores del mismo tipo y devuelve una matriz de ese tipo:
Una función que toma dos argumentos de diferentes tipos, devolviendo un objeto con
los vínculos apropiados ' x ' e ' y ' de esos tipos:
Una función que toma una matriz de un tipo y un argumento de función, devuelve una matriz de otro tipo, donde el
argumento de la función toma un valor del primer tipo de elemento de matriz y devuelve un valor del segundo tipo de
elemento de matriz:
3.9.2.2 Lista de parámetros
Una firma ' s lista de parámetros consta de cero o más exigidas parámetros, seguido de cero o más parámetros
opcionales, finalmente seguida por un parámetro resto opcional.
ParameterList:
RequiredParameterList
OpcionalParameterList
RestParameter
RequiredParameterList , OpcionalParameterList RequiredParameterList , RestParameter OpcionalParameterList ,
RestParameter RequiredParameterList , OpcionalParameterList , RestParameter
RequiredParameterList:
RequiredParameter
RequiredParameterList , RequiredParameter
RequiredParameter:
AccessibilityModifier BindingI dentifier OrPattern TypeAnnotation Binding Identifier : StringLiteral
opt opt
AccessibilityModifier :
público
privado
protegido
OpcionalParameterList:
OpcionalParameter
OpcionalParameterList , OpcionalParameter
Parámetro opcional:
AccessibilityModifier BindingI dentifier OrPattern ? Tipo
opt
RestParameter:
... BindingI dentifier TypeAnnotation
opt
Una declaración de parámetro puede especificar un identificador o un patrón de enlace ( 5.2.2 ). Los identificadores
especificados en las declaraciones de parámetros y los patrones de enlace en una lista de parámetros deben ser únicos
dentro de esa lista de parámetros.
Una anotación de tipo para un parámetro rest debe denotar un tipo de matriz.
Cuando un tipo de parámetro anotado especifica un tipo literal de cadena , la firma que contiene es una firma
especializada (sección 3.9.2.4 ). Las firmas especializadas no están permitidas junto con un cuerpo de función, es decir,
las producciones de
gramática FunctionExpression , FunctionImplementation , MemberFunctionImplementation y ConstructorImplementation no
permiten parámetros con tipos de cadenas literales.
Un parámetro puede marcarse como opcional siguiendo su nombre o patrón de enlace con un signo de interrogación
( ? ) O incluyendo un inicializador. Los inicializadores (incluidas las propiedades de enlace o los inicializadores de
elementos) solo se permiten cuando la lista de parámetros se produce junto con un cuerpo de función, es decir, solo
en una producción de gramática
de FunctionExpression , FunctionImplementation , MemberFunctionImplementation o ConstructorImplementation .
TODO: La actualización para reflejar el parámetro de enlace no puede ser opcional en la firma de implementación .
3.9.2.3 Tipo de devolución
Si está presente, una llamada de la firma ' s tipo de retorno de anotación especifica el tipo del valor calculado y devuelto
por una operación llamada . Se utiliza una anotación de tipo de retorno nulo para indicar que una función no tiene valor
de retorno.
Cuando se produce una firma de llamada sin anotación de tipo de retorno en un contexto sin cuerpo de función,
se supone que el tipo de retorno es Cualquier tipo.
W gallina una firma llamada con ningún tipo de retorno anotación se produce en un contexto que tiene un cuerpo de la
función ( en concreto, una implementación de la función , una implementación de la función miembro, o un miembro de
acceso declaración ) , el tipo de retorno se infiere de la cuerpo de la función como se describe en sección 6.3 .
3.9.2.4 Firmas especializadas
Cuando una anotación de tipo de parámetro especifica un tipo literal de cadena (sección 3.2.9 ), la firma que lo contiene
se considera una firma especializada. S pecialized firmas se utilizan para expresar patrones donde específicos valores de
cadena para algunos parámetros causan los tipos de otro parámetro s o el resultado de la función a ser más
especializada. Por ejemplo, la declaración
Documento de interfaz {
createElement (tagName: " div " ): HTMLDivElement;
createElement (tagName: " span " ): HTMLSpanElement;
createElement (tagName: " canvas " ): HTMLCanvasElement;
createElement (tagName: string ): HTMLElement;
}
Al escribir declaraciones sobrecargadas como la anterior, es importante enumerar la firma no especializada al final . Esto
se debe a que la resolución de sobrecarga (sección 4.15.1 ) procesa a los candidatos en orden de declaración y elige el
primero que coincida.
Cada especializada llamada o construir la firma en un tipo de objeto ha de ser asignables a al menos una no
especializado llamada o construir sig naturaleza en el mismo tipo de objeto (donde una firma llamada A se
considera un ssignable a otra firma llamada B si un tipo de objeto que contiene solo A sería asignable a un tipo de objeto
que solo contiene B ) . Por ejemplo, la propiedad ' createElement ' en el ejemplo anterior es de un tipo que contiene tres
firmas especializadas, todas las cuales son asignables a la firma no especializada en el tipo.
3.9.3 Construir firmas
Una construcción de la firma define la lista de parámetros y de retorno tipo asociado con la aplicación de
º e nuevo operador (sección 4.14 ) a una instancia del tipo que contiene. Un tipo puede SOBRECA d nueva oper un ciones
definiendo varios constructos firmas con diferentes parámetros listas .
ConstructSignature:
nuevo TypeParameters ( ParameterList ) TypeAnnotation
opt opt opt
Los parámetros de tipo, la lista de parámetros y el tipo de retorno de una firma de construcción están sujetos a las mismas
reglas que una firma de llamada .
3.9.4 Firmas de índice
Una firma de índice define una restricción de tipo para las propiedades en el tipo contenedor.
IndexSignature:
[ BindingI dentifier : string ] TypeAnnotation [ BindingI dentifier : number ] TypeAnnotation
Las firmas de índice de cadena , especificadas mediante una cadena de tipo de índice , definen restricciones de
tipo para todas las propiedades y firmas de índice numérico en el tipo que lo contiene. En concreto, en un tipo con
una firma de índice serie es de tipo T , todas las propiedades y firmas índice numérico deben tener tipos que
son asignables a T .
Las firmas de índice numérico , especificadas usando el número de tipo de índice , definen restricciones de tipo
para todas las propiedades con nombre numérico en el tipo que lo contiene. En concreto, en un tipo con una firma
índice numérico de tipo T , todas las propiedades numéricamente nombrados deben tener tipos que son asignables
a T .
Una propiedad con nombre numérico es una propiedad cuyo nombre es un literal numérico válido. Específicamente, una
propiedad con un nombre N para los que ToString (ToNumber ( N )) es idéntica a N , donde ToString y ToNumber son la
operación abstracta s se define en la especificación de ECMAScript.
Un tipo de objeto puede contener como máximo una firma de índice de cadena y una firma de índice numérico.
Las firmas de índice afectan la determinación del tipo que resulta de aplicar un acceso de propiedad de notación de
paréntesis a una instancia del tipo que lo contiene, como se describe en la sección 4.13 .
3.9.5 Método de firmas
La firma de un método es una forma abreviada de declarar una propiedad de un tipo de función.
es equivalente a
f : { <T1, T2, ...> (p1, p2, ...): R; <U1, U2, ...> (q1, q2, ...): S; ... } ;
{
func1 (x: número ): número ; // Método de firma func2 : (x: número )
=> número ; // F Tipo de unción literal FUNC3 : {(x: número ): número }; // O tipo de objeto
literal }
las propiedades ' func1 ' , ' func2 ' , y ' FUNC3 ' son todos del mismo tipo, a saber, un tipo de objeto con una sola firma
llamada de tomar un número y devolver un número. Del mismo modo, en el tipo de objeto
{
func4 (x: número ): número ;
func4 (s: cadena ): cadena ;
func5 : {
(x: número ): número ;
(s: cadena ): cadena ;
};
}
los Properti es ' func4 ' y ' Func5 ' son del mismo tipo, es decir, un tipo de objeto con dos firmas llamada que toma y
volviendo número y secuencia, respectivamente.
3.10 Alias de tipo
Un tipo de alias decla ración introduce un tipo alias en el que contiene espacio de declaración .
TypeAliasDeclaration:
type BindingI dentifier TypeParameters = Type ;
opt
Un alias de tipo sirve como un alias para el tipo especificado en la declaración de alias de tipo. A diferencia de una
declaración de interfaz , que siempre introduce un tipo de objeto con nombre , una declaración de alias de tipo
puede introducir un nombre para cualquier tipo de tipo , incluidos los tipos primitivos, de unión e intersección .
Un alias de tipo puede tener opcionalmente parámetros de tipo (sección 3.6.1 ) que sirven como marcadores de posición
para los tipos reales que se proporcionarán cuando se haga referencia al alias de tipo en las referencias de tipo. Un alias
de tipo con parámetros de tipo se denomina alias de tipo genérico . Los parámetros de tipo de una declaración de alias
de tipo genérico están dentro del alcance y pueden referenciarse en el Tipo con alias .
Los alias de tipo se referencian utilizando referencias de tipo ( 3.8.2 ). Las referencias de tipo a los alias de tipo genérico
producen instancias del tipo con alias con los argumentos de tipo dados. Escribir una referencia a un alias de tipo no
genérico tiene exactamente el mismo efecto que escribir el tipo con alias , y escribir una referencia a un alias de tipo
genérico tiene exactamente el mismo efecto que escribir la instanciación resultante del tipo con alias.
El dentificador BindingI de una declaración de alias de tipo puede no ser uno de los nombres de tipo predefinidos
(sección 3.8.1 ).
Es un error que el tipo especificado en un alias de tipo dependa de ese alias de tipo. Los tipos tienen las
siguientes dependencias:
Dada esta definición, el conjunto completo de tipos de los que depende un tipo es el cierre transitivo del directamente
depende de la relación. Tenga en cuenta que los literales de tipo de objeto, los literales de tipo de función y los literales de
tipo de constructor no dependen de los tipos a los que se hace referencia en ellos y, por lo tanto, se les permite hacer
referencia circular a sí mismos a través de los tipos alias .
escriba StringOrNumber = string | número ;
escriba Texto = cadena | {texto: cadena };
escriba NameLookup = Dictionary < string , Person>;
type ObjectStatics = typeof Object;
tipo de devolución de llamada <T> = (datos: T ) => vacío ;
tipo Par <T> = [T, T] ; tipo Coordenadas = Par < número >; escriba Árbol <T> = T | {izquierda: árbol
<T>, derecha: árbol <T>};
Tipos de interfaz tienen muchas similitudes a teclear ali a ses para literales de tipo de objeto, pero dado que los tipos de
interfaz ofrecen más capacidades que son generalmente preferidos para escribir alias. Por ejemplo, el tipo de interfaz
Punto de interfaz {
x: número ;
y: número ;
}
tipo Punto = {
x: número ;
y: número ;
};
Sin embargo, hacerlo significa que se pierden las siguientes capacidades:
Una interfaz se puede nombrar en una cláusula de extensiones o implementos , pero un alias de tipo para un tipo
de objeto literal no .
Una interfaz puede tener varias declaraciones fusionadas, pero un alias de tipo para un literal de tipo de objeto no
puede .
3.11 Relaciones de tipo
Los tipos en TypeScript tienen relaciones de compatibilidad de identidad, subtipo, supertipo y asignación como se define
en las siguientes secciones.
3.11.1 Miembros aparentes
Los miembros aparentes de un tipo son los miembros observados en las relaciones de compatibilidad de subtipo,
supertipo y asignación, así como en la verificación de tipos de accesos a propiedades (sección 4.13 ), nuevasoperaciones
(sección 4.14 ) y llamadas a funciones (sección 4.15 ). Los un miembros pParent de un tipo se determinaron como sigue:
Los miembros aparentes del tipo primitivo Number y todos los tipos de enumeración son los miembros aparentes
del tipo de interfaz global 'Number'.
Los miembros aparentes del tipo primitivo Boolean son los miembros aparentes del tipo de
interfaz global 'Boo lean' .
Los miembros aparentes del tipo String primitivo y todos los tipos literales de cadena son los miembros aparentes
del tipo de interfaz global 'String'.
Los miembros aparentes de un parámetro de tipo son los miembros aparentes de la restricción (sección 3.6.1 ) de
ese parámetro de tipo.
Los miembros aparentes de un tipo de objeto T son la combinación de lo siguiente:
o Los declarados y / o los miembros heredados de T .
o Las propiedades de la interfaz típ mundial e 'Objeto' que no se oculta b propiedades Y con el mismo
nombre en la camiseta .
o Si T tiene uno o más cal l o construir firmas, las propiedades del tipo de interfaz global 'Función' que no
se oculta por propiedades con el mismo nombre en la camiseta .
Los miembros aparentes de una unión tipo U se determinan de la siguiente manera:
o Cuando todos los tipos constituyentes de U tienen una n propiedad aparente llamada N , U tiene una
propiedad aparente llamada N de un tipo de unión de los respectivos tipos de propiedad.
o Cuando todos los tipos constituyentes de U tienen una firma de llamada aparente n con una lista de
parámetros P , U tiene una firma de llamada aparente con la lista de parámetros P y un tipo de retorno que
es una unión de los tipos de retorno respectivos. Las firmas de llamada aparecen en el mismo orden que en
el primer tipo de componente.
o Cuando todos los tipos constituyentes de U tienen una firma de construcción aparente n con una lista de
parámetros P , U tiene una firma de construcción aparente con la lista de parámetros P y un tipo de
retorno que es una unión de los tipos de retorno respectivos. Las firmas de construcción aparecen en el
mismo orden que en el primer tipo de componente.
o Cuando todos los tipos constituyentes de U tienen una firma de índice de cadena aparente n , U tiene
una firma de índice de cadena aparente n de un tipo de unión de los tipos de firma de índice de cadena
respectivos.
o Cuando todos los tipos constituyentes de U tienen una firma de índice numérico aparente, U tiene una
firma de índice numérico aparente de un tipo de unión de los tipos de firma de índice numérico
respectivos.
Los miembros aparentes de una intersección tipo I se determinan de la siguiente manera:
o Cuando uno de los tipos más constituyentes de I tiene una propiedad aparente llamada N , tengo una
propiedad aparente llamada N de un tipo de intersección n de los tipos de propiedad respectivos.
o Cuando uno o más tipos constitutivos de I tienen una firma llamada S , I tiene la aparente firma
llamada S . Las firmas están clasificadas como una concatenación de las firmas de cada tipo de componente
en el orden de los tipos de constituyentes dentro de I .
o Cuando uno o más tipos constitutivos de I tienen una firma constructo S , I tiene la aparente firma
constructo S . Las firmas están clasificadas como una concatenación de las firmas de cada tipo de
componente en el orden de los tipos de constituyentes dentro de I .
o Cuando uno o más tipos constituyentes de I tienen una firma de índice de cadena aparente, tengo una
firma de índice de cadena aparente de un tipo de intersección de los respectivos tipos de firma de índice de
cadena.
o Cuando uno o más tipos constituyentes de I tienen una firma de índice numérico aparente, tengo una
firma de índice numérico aparente de un tipo de intersección de los tipos de firma de índice numérico
respectivos.
Algunos ejemplos:
El último trabajo es un error porque el objeto literal que tiene un ' toString ' método que ISN ' t compatible con el
de ' Objeto ' .
Dos firmas de llamada o construcción se consideran idénticas cuando tienen el mismo número de parámetros de tipo con
restricciones de parámetros de tipo idénticas y, después de sustituir el tipo Cualquiera por los parámetros de tipo
introducidos por las firmas, un número idéntico de parámetros con tipo idéntico (requerido, opcional o resto) y tipos, y
tipos de retorno idénticos.
Tenga en cuenta que, a excepción de los tipos primitivos y las clases con miembros privados o protegidos , es la
estructura, no el nombre, de los tipos lo que determina la identidad. Además, tenga en cuenta que los nombres de los
parámetros no son significativos al determinar la identidad de las firmas.
P rivado y protegidas Propert IES coinciden sólo si se originan en la misma declaración y tienen tipos idénticos. Dos tipos
distintos pueden contener propiedades que se originan en la misma declaración si los tipos son referencias
parametrizadas separadas a la misma clase genérica. En el ejemplo
las variables ' a ' y ' b ' son de tipos idénticos porque las dos referencias de tipo a ' C ' crean tipos con un miembro
privado ' x ' que origina s en la misma declaración, y porque los dos miembros privados ' x ' tienen tipos con conjuntos
idénticos de miembros una vez que se sustituyen los argumentos de tipo ' X ' e ' Y ' .
3.11.3 Subtipos y Supertipos
S es un subtipo de un tipo T , y T es un supertipo de S , si S no tiene propiedades en exceso con respecto a T ( 3.11.5 )
y uno de los siguientes es verdadero :
Al comparar las firmas de llamada o construcción , los nombres de los parámetros se ignoran y los parámetros de
descanso corresponden a una expansión ilimitada de parámetros opcionales del tipo de elemento de parámetro de
descanso.
Tenga en cuenta que las firmas especializadas de llamada y construcción (sección 3.9.2.4 ) no son significativas al
determinar las relaciones de subtipo y supertipo.
También tenga en cuenta que los parámetros de tipo no se consideran tipos de objeto. Por lo tanto, los únicos subtipos
de un parámetro de tipo T son T sí mismo y otros parámetros de tipo que están restringidas directa o indirectamente a T .
3.11.4 Compatibilidad de asignación
Se requieren tipos de b correo asignación compatibles en ciertas circunstancias, como expresión y tipos de variables en
instrucciones de asignación y los tipos de argumentos y parámetros en las llamadas a funciones.
S es asignable a un tipo T , y T es asignable desde S , si S no tiene propiedades en exceso con respecto a T ( 3.11.5 )
y uno de los siguientes es cierto:
Al comparar firmas de llamada o construcción, los nombres de los parámetros se ignoran y los parámetros de descanso
corresponden a una expansión ilimitada de parámetros opcionales del tipo de elemento de parámetro de descanso.
Tenga en cuenta que las firmas especializadas de llamada y construcción (sección 3.9.2.4 ) no son significativas al
determinar la compatibilidad de la asignación.
3.11.5 Exceso de propiedades
Las relaciones de compatibilidad de subtipo y asignación requieren que los tipos de origen no tengan propiedades en
exceso con respecto a los tipos de destino ir . El propósito de esta verificación es detectar propiedades en exceso o mal
escritas en literales de objeto.
Se considera que un tipo de fuente S tiene propiedades en exceso con respecto a un tipo de destino T si
El tipo inferido para un objeto literal (como se describe en la sección 4.5 ) se considera un tipo literal de
objeto fr esh . La frescura desaparece cuando se amplía un tipo literal de objeto ( 3.12 ) o es el tipo de la expresión en
una aserción de tipo ( 4.16 ).
interfaz CompilerOptions {
estricto ?: booleano ;
sourcePath ?: cadena ;
targetPath ?: cadena ;
}
opciones var : CompilerOptions = {
estricto: verdadero ,
ruta de origen : "./src" , // Error, exceso o m propiedad
emitida targetpath : "./bin" // Error, propiedad excesiva o mal escrita } ;
El tipo 'CompilerOptions' contiene solo propiedades opcionales, por lo que sin la comprobación de propiedad en
exceso, cualquier objeto literal se podría asignar a la variable 'opciones' (porque una propiedad mal escrita solo se
consideraría una propiedad en exceso de un nombre diferente).
En los casos en que se espera un exceso de propiedades, se puede agregar una firma de índice al tipo de destino como un
indicador de intención:
interfaz InputElement {
nombre: cadena ;
visible ?: booleano ;
[x: cadena ]: cualquiera ; // Permitir propiedades adicionales de cualquier tipo }
dirección var : InputElement = {
nombre: "Dirección" ,
visible: verdadero ,
ayuda: "Ingrese la dirección aquí" , // Permitido debido a
acceso directo de firma de índice : "Alt-A" // Permitido debido a firma de índice };
Usando el proceso descrito en 3.11.7 , inferencias para A ' parámetros de tipo s se hacen de cada tipo de
parámetro en B en el correspondiente tipo de parámetro en A para aquellas posiciones de parámetros que están
presentes en ambos signatur es , donde los parámetros de descanso corresponden a una ilimitada expansión de
parámetros opcionales del tipo de elemento del parámetro rest.
El argumento de tipo inferido para cada parámetro tipo es el tipo de unión del conjunto de inferencias hechas
para el th en el tipo de parámetro. Sin embargo, si el tipo de unión no satisface la restricción del parámetro de tipo,
el argumento de tipo inferido es en cambio la restricción.
3.11.7 Inferencia de tipo
En ciertos contextos, las inferencias para un conjunto dado de parámetros de tipo se hacen de un tipo S , en el
que esos parámetros de tipo no ocurren, a otro tipo T , en el que esos parámetros de tipo sí ocurren. Las inferencias
consisten en un conjunto de argumentos de tipo candidato recopilados para cada uno de los parámetros de tipo. El
proceso de inferencia relaciona recursivamente S y T para reunir tantas inferencias como sea posible:
Si T es uno de los parámetros de tipo para el que se están haciendo inferencias, S se agrega al conjunto de
inferencias para ese parámetro de tipo.
De lo contrario, si S y T son referencias al mismo tipo genérico, inferencias se hacen de cada argumento tipo
en S para cada argumento tipo correspondiente en T .
De lo contrario, si S y T son tipos de tupla con el mismo número de elementos, inferencias se hacen de cada tipo
de elemento en S para cada tipo de elemento correspondiente en T .
De lo contrario, si T es una unión o intersección tipo :
o En primer lugar, inferencias están hechos de S a cada tipo de constituyente en T que
ISN ' t simplemente uno de los parámetro de tipo para el que se están haciendo inferencias s .
o Si el primer paso no produjo inferencias, entonces si T es un tipo de unión y exactamente un tipo
constituyente en T es simplemente un parámetro de tipo para el cual se están haciendo inferencias, las
inferencias se hacen de S a ese parámetro de tipo.
De lo contrario, si S es una unión o intersección tipo , inferencias se hacen de cada tipo de constituyente
en S a T .
De lo contrario, si S y T son tipos de objeto, entonces para cada miembro M en T :
o Si M es una propiedad y S contiene una propiedad N con el mismo nombre que M , inferencias se hacen
con el tipo de N al tipo de M .
o Si M es una firma de llamada y existe una firma de llamada correspondiente N en S , N se instancia con el
tipo Any como argumento para cada parámetro de tipo (si lo hay) y se hacen inferencias de los tipos de
parámetros en N a los tipos de parámetros correspondientes en M para las posiciones que están presentes
en ambas firmas, y desde el tipo de retorno de N para el tipo de retorno de M .
o Si M es una firma de construcción y existe una firma de construcción correspondiente N en S , N se
instancia con el tipo Any como argumento para cada parámetro de tipo (si lo hay) y se hacen inferencias de
los tipos de parámetros en N a los tipos de parámetros correspondientes en M para las posiciones que
están presentes en ambas firmas, y desde el tipo de retorno de N para el tipo de retorno de M .
o Si M es una firma de índice cadena y S contiene una firma de índice cadena de N , inferencias se hacen
con el tipo de N al tipo de M .
o Si M es una firma índice numérico y S contiene un índice de firma numérica N , inferencias se hacen con
el tipo de N al tipo de M .
o Si M es una firma de índice numérico y S contiene una firma de índice cadena de N , inferencias se hacen
con el tipo de N al tipo de M .
Al comparar firmas de llamada o de construcción, las firmas en S corresponden a firmas del mismo tipo en T por pares en
orden de declaración. Si S y T tienen números diferentes de un tipo dado de firma, se ignoran las primeras firmas
en exceso en el orden de declaración de la lista más larga.
3.11.8 Tipos recursivos
Las clases y las interfaces pueden referenciarse a sí mismas en su estructura interna, en efecto creando tipos recursivos
con anidamiento infinito. Por ejemplo, el tipo
contiene una secuencia infinitamente anidada de propiedades ' siguientes ' . Tipos como este son perfectamente válidos
pero requieren un tratamiento especial al determinar las relaciones de tipo. Específicamente, al comparar los
tipos S y T para una relación dada (identidad, subtipo o asignabilidad), se asume que la relación en cuestión es verdadera
para cada ocurrencia anidada directa o indirectamente de la misma S y la misma T (donde lo mismo significa origen en la
misma declaración y, si corresponde, con argumentos de tipo idéntico ). Por ejemplo, considere la relación de identidad
entre ' A ' arriba y ' B ' abajo:
Cuando se utiliza esta misma técnica para comparar referencias de tipo genérico, dos referencias de tipo se consideran
iguales cuando se originan en la misma declaración y tienen argumentos de tipo idénticos.
Lista de interfaz <T> {
datos: T;
siguiente: Lista < T>;
propietario: Lista <Lista <T>>;
}
nombre var = " Steve " ;
infiere que el tipo de ' nombre ' será el tipo primitivo S tring ya que ese es el tipo del valor utilizado para inicializarlo. Al
inferir el tipo de resultado de una variable, propiedad o función de una expresión, la forma ampliada del tipo de origen
se utiliza como el tipo inferido del destino. La forma ampliada de un tipo es el tipo en el que todas las apariciones de
los tipos N ull y U ndefined se han reemplazado por el tipo any .
El siguiente ejemplo muestra los resultados de la ampliación de tipos para producir tipos de variables inferidas.
1
4 expresiones
4.1 Valores y referencias
Las expresiones se clasifican como valores o referencias . Las referencias son el subconjunto de expresiones que se
permiten como destino de una asignación. Específicamente, las referencias son combinaciones
de i dentifiers (sección 4.3 ), paréntesis (sección 4.8 ), y la propiedad de un ccesses (sección 4.13 ). A ll otros constructos de
expresión descritos en este capítulo se clasifican como valores.
4.2 4.2 La esta palabra clave
El tipo de esto en una expresión depende de la ubicación en la que tiene lugar la referencia:
En todos los demás contextos, es un error en tiempo de compilación hacer referencia a esto .
Tenga en cuenta que una función de la flecha (sección 4.11 ) no tiene este parámetro sino que preserva el este de su
contexto circundante.
4.3 4.3 Identificadores
Cuando una expresión es una referencia de identificador , la expresión se refiere al espacio de nombres ,
clase, enumeración, función, variable o parámetro más anidados con ese nombre cuyo alcance (sección 2.4 ) incluye la
ubicación de la referencia. El tipo de un tal expr esión es el tipo asociado con la entidad referenciada:
Para un espacio de nombres , el tipo de objeto asociado con la instancia del espacio de nombres .
Para una clase, el tipo de constructor asociado con el objeto de función de constructor.
Para una enumeración, el tipo de objeto asociado con el objeto enumeración.
Para una función, el tipo de función asociado con el objeto de función.
Para una variable, el tipo de la variable.
Para un parámetro, el tipo del parámetro.
Una expresión de identificador que hace referencia a una variable o parámetro se clasifica como referencia. Una expresión
de identificador que hace referencia a cualquier otro tipo de entidad se clasifica como un valor (y, por lo tanto, no puede
ser el objetivo de una asignación).
4.4 Literales
Los literales se escriben de la siguiente manera:
GetAccessor:
get PropertyName ( ) TypeAnnotation { FunctionBody }
opt
SetAccessor:
set PropertyName ( BindingI dentifier OrPattern TypeAnnotation ) { FunctionBody }
opt
El tipo de un objeto literal es un tipo de objeto con el conjunto de propiedades especificadas por las asignaciones de
propiedades en el objeto literal. Un descriptor de acceso get and set puede especificar el mismo nombre de propiedad,
pero de lo contrario es un error especificar múltiples asignaciones de propiedad para la misma propiedad.
apuntalar
es equivalente a
prop: prop
f (...) { ... }
es equivalente a
f : función (...) {...}
Si el objeto literal se escribe contextualmente y el tipo contextual contiene una propiedad con un nombre
coincidente, la asignación de propiedad se escribe contextualmente por el tipo de esa propiedad.
De lo contrario, si el literal del objeto se escribe contextualmente, si el tipo contextual contiene una firma de
índice numérico, y si la asignación de propiedad especifica un nombre de propiedad numérico, la asignación de
propiedad se escribe contextualmente por el tipo de firma de índice numérico.
De lo contrario, si el objeto literal se escribe contextualmente y el tipo contextual contiene una firma de índice de
cadena, la asignación de propiedad se escribe contextualmente por el tipo de firma de índice de cadena.
De lo contrario, la asignación de propiedad se procesa sin un tipo contextual.
El tipo de propiedad introducida por una asignación de propiedad del formulario Nombre : Expr es el tipo de Expr .
Una declaración get accessor se procesa de la misma manera que una declaración de función ordinaria (sección 6.1 ) sin
parámetros . Una declaración de conjunto de acceso se procesa de la misma manera que una declaración de función
ordinaria con un único parámetro y un tipo de retorno Anulado. Cuando se declara un descriptor de acceso get y set para
una propiedad :
Si ambos accesos incluyen anotaciones de tipo, los tipos especificados deben ser idénticos.
Si solo un descriptor de acceso incluye una anotación de tipo, el otro se comporta como si tuviera la misma
anotación de tipo.
Si ninguno de los descriptores de acceso incluye una anotación de tipo, el tipo de retorno inferido del descriptor
de acceso get se convierte en el tipo de parámetro del descriptor de acceso establecido.
Si se declara un descriptor de acceso para una propiedad, el tipo de retorno del descriptor de acceso se convierte en el
tipo de la propiedad. Si solo se declara un conjunto de accesos para una propiedad, el tipo de parámetro (que puede ser
de tipo Cualquiera si no hay ninguna anotación de tipo) del conjunto de accesos se convierte en el tipo de la propiedad.
Cuando un literal de objeto se escribe contextualmente por un tipo que incluye una firma de índice de cadena , el tipo
resultante del literal de objeto incluye una firma de índice de cadena con el tipo de unión de los tipos de las propiedades
declaradas en el literal de objeto, o el tipo Indefinido si El objeto literal está vacío. Del mismo modo, cuando un literal de
objeto se escribe contextualmente por un tipo que incluye una firma de índice numérico, el tipo resultante del literal de
objeto incluye una firma de índice numérico con el tipo de unión de los tipos de las propiedades con nombre numérico
(sección 3.9.4 ) declaradas en el objeto literal, o el tipo Indefinido si el objeto literal no declara propiedades con nombre
numérico.
Si el PropertyName de una asignación de propiedad es un nombre de propiedad calculado que no denota un símbolo
conocido ( 2.2.3 ), la construcción se considera una asignación de propiedad dinámica . Las siguientes reglas se aplican
a las asignaciones de propiedades dinámicas:
Una asignación de propiedad dinámica no introduce una propiedad en el tipo del objeto literal.
La expresión del nombre de propiedad de una asignación de propiedad dinámica debe ser del tipo Cualquiera o
del tipo primitivo Cadena, Número o Símbolo.
El nombre asociado con una asignación de propiedad dinámica se considera un nombre de propiedad numérico
si la expresión del nombre de propiedad es de tipo Any o del tipo primitivo Number.
4.6 Array Literals
Una matriz literal
Si el literal de matriz está vacío, el tipo resultante es un tipo de matriz con el tipo de elemento Indefinido.
De lo contrario, si el literal de matriz no contiene elementos de propagación y está tipeado contextualmente por
un tipo similar a una tupla (sección 3.3.3 ) , el tipo resultante es un tipo de tupla construido a partir de los tipos de
las expresiones del elemento.
De lo contrario, si el literal de matriz no contiene elementos extendidos y es un patrón de asignación de matriz en
una asignación de desestructuración (sección 4.21.1 ), el tipo resultante es un tipo de tupla construido a partir de los
tipos de las expresiones de elementos.
De lo contrario , el tipo resultante es un tipo de matriz con un tipo de elemento que es la unión de los tipos
de expresiones de elementos no extendidos y los tipos de firma de índice numérico de las expresiones de elementos
extendidos.
TODO: el compilador actualmente no admite la aplicación del operador de propagación a una cadena (para
distribuir los caracteres individuales de una cadena en una matriz de cadenas ) . Esto eventualmente se permitirá, pero solo
cuando el objetivo de generación de código sea ECMAScript 2015 o posterior .
TODO: documento que propaga un iterador en una matriz literal .
Las reglas anteriores significan que un literal de matriz siempre es de un tipo de matriz, a menos que esté contextualizado
por un tipo similar a una tupla . Por ejemplo
Cuando el objetivo de salida es ECMAScript 3 o 5, los literales de matriz que contienen elementos extendidos se
reescriben para invocaciones del método concat . Por ejemplo, las tareas
son reescritos a
4.7 Literales de plantilla
TODO: Literales de plantilla .
4.8 Paréntesis
Una expresión entre paréntesis
( expr )
4.9.1 Super llamadas
S uper llaman s consisten en la palabra clave súper seguido por una lista de argumentos entre paréntesis. Las súper
llamadas solo se permiten en constructores de clases derivadas , como se describe en la sección 8.3.2 .
Una llamada súper invoca al constructor de la clase base en el ejemplo al que hace referencia este . Una súper llamada se
procesa como una llamada de función (sección 4.15 ) utilizando las firmas de construcción del tipo de función
de constructor de clase base como el conjunto inicial de firmas candidatas para la resolución de sobrecarga. Los
argumentos de tipo no se pueden especificar explícitamente en una súper llamada. Si la clase base es una clase genérica,
los argumentos de tipo utilizados para procesar una súper llamada son siempre los especificados en
la cláusula extendidas que hace referencia a la clase base.
S de propiedad uper de acceso es son no permitidos en otros contextos, y T no es posible acceder a otros tipos de
miembros de la clase base en un acceso a la propiedad de super. Tenga en cuenta que los accesos de súper propiedades
no están permitidos dentro de las expresiones de función anidadas en las construcciones anteriores porque esto es del
tipo Cualquiera en tales expresiones de función.
En el Super accesos se utilizan normalmente para acceder OVERRID funciones miembro de la clase base del den de
miembro de clase derivados funciones . Para un ejemplo de esto, vea la sección 8.4.2 .
TODO: sección de actualización para incluir notación de corchetes en el acceso a la propiedad súper .
Las descripciones de las declaraciones de funciones proporcionadas en el capítulo 6 se aplican también a las expresiones
de funciones, excepto que las expresiones de funciones no admiten sobrecarga.
El tipo de una expresión de función es un tipo de objeto que contiene un solo firma llamada con tipos de parámetros y de
retorno inferidos a partir de la expresión de función ' firma s y el cuerpo.
Cuando una expresión de función sin parámetros de tipo y sin anotaciones de tipo de parámetro se tipea contextualmente
(sección 4.23 ) mediante un tipo T y se puede extraer una firma contextual S de T , la expresión de función se procesa
como si hubiera especificado explícitamente anotaciones de tipo de parámetro como existen en S . Los parámetros se
corresponden por posición y no necesitan tener nombres coincidentes . Si la expresión de la función tiene menos
parámetros que S , los parámetros adicionales en S se ignoran. Si la expresión de función tiene más parámetros que S , se
considera que todos los parámetros adicionales tienen el tipo Any.
Del mismo modo, cuando una expresión de función sin anotación de tipo de retorno se tipea contextualmente
(sección 4.23 ) por un tipo de función T y se puede extraer una firma contextual S de T , las expresiones en declaraciones
de retorno contenidas (sección 5.10 ) se tipean contextualmente por el tipo de retorno de S .
Una firma contextual S se extrae de una función tipo T de la siguiente manera:
Si T es un tipo de función con exactamente una firma de llamada, y si esa firma de llamada no es genérica, S es
esa firma.
Si T es un tipo de unión, sea U el conjunto de tipos de elementos en T que tienen firmas de llamada. Si cada tipo
en U tiene exactamente una firma de llamada y esa firma de llamada no es genérica, y si todas las firmas son
idénticas ignorando los tipos de retorno, entonces S es una firma con los mismos parámetros y una unión de los
tipos de retorno.
De lo contrario, ninguna firma contextual se puede extraer de T .
En el ejemplo
la expresión de la función se tipea contextualmente por el tipo de 'f', y dado que la expresión de la función no tiene
parámetros de tipo ni anotaciones de tipo, su información de tipo de parámetro se extrae del tipo contextual, infiriendo
así el tipo de 's' para ser la primitiva String tipo.
4.11 Flecha Función s
Las funciones de flecha se extienden desde JavaScript para incluir opcionalmente parámetros y anotaciones de tipo de
retorno.
Las descripciones de las declaraciones de funciones proporcionadas en el capítulo 6 se aplican también a las funciones de
flecha, excepto que las funciones de flecha no admiten sobrecarga.
El tipo de una función de flecha se determina de la misma manera que una expresión de función (sección 4.10 ). Del
mismo modo, los parámetros de una función de flecha y las declaraciones de retorno en el cuerpo de una función de
flecha se escriben contextualmente de la misma manera que para las expresiones de función.
Cuando una función de flecha con un cuerpo de expresión y no el tipo de retorno de anotación se contextualmente
mecanografiado (sección 4.23 ) por un tipo de función de T y una firma contextual S se puede extraer de T , el cuerpo de
expresión se contextualmente tecleado por el tipo de retorno de S .
es exactamente equivalente a
(...) => { return expr ; }
id => {...}
id => expr
Una expresión de función introduce un nuevo límite dinámico de esto , mientras que una expresión de función de
flecha conserva el presente de su contexto envolvente. Expresiones de función Flecha son particularmente útiles para la
escritura de devolución de llamada s, que de otro modo a menudo tienen un n indefinido o inesperado este .
En el ejemplo
clase Messenger {
mensaje = " Hola Mundo " ;
start () {
setTimeout (() => alert ( this .message), 3000 );
}
};
var messenger = nuevo Messenger ();
messenger.start ();
el uso de una expresión de la función de devolución de llamada flecha hace que el tener el mismo presente como el que
rodea a ' inicio ' método . Escribiendo la devolución de llamada como un estándar de la función de la expresión se hace
necesario organizar manualmente el acceso a los alrededores de este , por ejemplo mediante la copia en una variable
local:
clase Messenger {
mensaje = " Hola Mundo " ;
start () { var _this = this ; setTimeout ( function () {alert
(_this.message);}, 3000 ); } };
Una construcción de la forma
podría analizarse como una expresión de función de flecha con un parámetro de tipo o una aserción de tipo aplicada a
una función de flecha sin parámetro de tipo. Se resuelve como el primero, pero se pueden usar paréntesis para seleccionar
el segundo significado:
4.12 Expresiones de clase
TODO: Expresiones de clase de documento .
4.13 Acceso a la propiedad
Un acceso de propiedad utiliza notación de punto o notación de corchete. Una expresión de acceso a la propiedad
siempre se clasifica como referencia.
Un acceso a la propiedad de notación de puntos del formulario
objeto . nombre
donde object es una expresión y n ame es un identificador (que incluye, posiblemente, una palabra reservada ) , se utiliza
para acceder a la propiedad con el nombre dado en el objeto dado . El acceso a la propiedad de notación de puntos se
procesa de la siguiente manera en tiempo de compilación:
Si objeto es de tipo A ny , cualquier n AME está permitido y el acceso a la propiedad es de tipo Cualquier.
De lo contrario, si n AME denota un n accesible aparente propiedad (sección 3.11.1 ) en
el ensanchada tipo (sección 3.12 ) de objeto , el acceso a la propiedad es del tipo de esa propiedad . Los miembros
públicos siempre son accesibles, pero los miembros privados y protegidos de una clase tienen accesibilidad
restringida, como se describe en 8.2.2 .
De lo contrario, el acceso a la propiedad no es válido y se produce un error en tiempo de compilación.
objeto [ índice ]
donde objeto e índice son expresiones, se utiliza para acceder a la propiedad con el nombre calculado por la expresión de
índice en el objeto dado. El acceso a la propiedad de notación de corchetes se procesa de la siguiente manera en tiempo
de compilación:
Las reglas anteriores significan que las propiedades están fuertemente tipadas cuando se accede mediante notación de
corchetes con la representación literal de su nombre. Por ejemplo:
var type = {
name: " boolean " ,
primitive: true
};
var s = tipo [ " nombre " ]; // string
var b = type [ " primitivo " ]; // booleano
Los tipos de tupla asignan nombres numéricos a cada uno de sus elementos y, por lo tanto, los elementos se escriben
fuertemente cuando se accede mediante la notación de corchetes con un literal numérico:
nueva C
nueva C (...)
nueva C <...> ( ... )
donde C es una expresión. La primera forma es equivalente a proporcionar una lista de argumentos vacía. C debe ser
del tipo A ny o de un tipo de objeto con una o más construcciones o firmas de llamada . La operación se procesa de la
siguiente manera en tiempo de compilación:
Si C es de tipo A ny , se permite cualquier lista de argumentos y el resultado de la operación es de tipo A ny .
Si C tiene una o más firmas de construcción aparentes (sección 3.11.1 ) , la expresión se procesa de la misma
manera que una llamada a función , pero usando las firmas de construcción como el conjunto inicial de firmas
candidatas para la resolución de sobrecarga. El tipo de resultado de la llamada de función se convierte en el tipo de
resultado de la operación.
Si C no tiene firmas de construcción aparentes, sino una o más firmas de llamada aparentes , la expresión se
procesa como una llamada a función. Se produce un error en tiempo de compilación si el resultado de la llamada a
la función no es Anulado. El tipo del resultado de la operación es A ny .
4.15 Llamadas de funciones
Las llamadas a funciones se extienden desde JavaScript para apoyar op argumentos de tipo cionales.
func ( ...)
func < ... > ( ... )
donde func es una expresión de un tipo de función o de cualquier tipo . La expresión de función es seguida por una lista
de argumentos de tipo opcional (sección 3.6.2 ) y una lista de argumentos n .
4.15.1 Resolución de sobrecarga
El propósito de la resolución de sobrecarga en una llamada de función es asegurar que al menos una firma es
aplicable, para proporcionar tipos contextuales de los argumentos , y para determinar el nuevo tipo sultado de la llamada
a la función , que podría diferir entre las múltiples firmas aplicables . La resolución de sobrecarga no tiene impacto en el
comportamiento en tiempo de ejecución de una llamada de función. Desde JavaScript doesn ' sobrecarga de funciones de
soporte t, lo único que importa en tiempo de ejecución es el nombre de la función.
Se dice que una firma es una firma aplicable con respecto a una lista de argumentos cuando
TODO: Operador extendido en llamadas a funciones y esparciendo un iterador en una llamada a funciones .
más del tipo parámetros T , y una lista de argumentos ( e , e , ..., e ), la tarea de inferencia de argumentos de tipo es
1 2 m
encontrar un conjunto de argumentos de tipo A ... A para sustituir a T ... T modo que la lista de argumentos se
1 n 1 n de
TODO: Actualización de inferencia de argumentos de tipo y reglas de resolución de sobrecarga .
La inferencia de argumento de tipo produce un conjunto de tipos candidatos para cada parámetro de tipo. Dado un
parámetro de tipo T y un conjunto de tipos candidatos, el argumento de tipo inferido real se determina de la siguiente
manera:
Si el conjunto de tipos de argumentos candidatos está vacío, el argumento de tipo inferido de T es T ' restricción
s.
De lo contrario, si al menos uno de los tipos candidatos es un supertipo de todos los otros tipos candidatos,
dejemos que C denote la forma ampliada (sección 3.12 ) del primer tipo de candidato. Si C satisface T ' s limitación,
el argumento de tipo inferido de T es C . De lo contrario, el argumento de tipo inferido de T es T ' restricción s.
De lo contrario, si no hay tipo de candidato es un supertipo de todos los otros tipos de candidatos , la inferencia
de tipos ha falla y ningún tipo argumento se infiere de T .
Para calcular los tipos de candidatos , la lista de argumentos se procesa de la siguiente manera:
Inicialmente, un ll tipo inferidos argumentos se consideran no fijado con un conjunto vacío de tipos de
candidatos .
Procediendo de izquierda a derecha, cada expresión argumento e se inferencia escrito por su correspondiente
tipo de parámetro P , posiblemente causando algunos argumentos de tipo inferidos a convertirse fijo , y las
inferencias de tipo candidato (sección 3.11.7 ) están hechos para no fijadas argumentos de tipo inferidos a partir del
tipo calculado para e a P .
El proceso de escribir inferencialmente una expresión e por un tipo T es el mismo que el de escribir
contextualmente e por T , con las siguientes excepciones:
Un ejemplo :
En la primera llamada a ' elegir ' , se hacen dos inferencias de ' número ' a ' T ' , una para cada parámetro. Por lo
tanto, ' número ' se infiere para ' T ' y la llamada es equivalente a
En la segunda llamada a ' elegir ' , se hace una inferencia del tipo ' cadena ' a ' T ' para el primer parámetro y se hace una
inferencia del tipo ' número ' a ' T ' para el segundo parámetro. Como ni ' string ' ni ' number ' son un supertipo del otro,
la inferencia de tipos falla . Eso a su vez significa que no hay firmas aplicables y que la llamada a la función es un error.
En el ejemplo
mapa de funciones <T, U> (a: T [], f: (x: T) => U): U [] { resultado var : U [] = []; for ( var i = 0 ;
i <a.length; i ++) result.push (f (a [i])); resultado de retorno ; }
nombres var = [ " Peter " , " Paul " , " Mary " ];
var lengths = map (nombres, s => s.length);
Las inferencias para ' T ' y ' U ' en la llamada a ' map ' se hacen de la siguiente manera: para el primer parámetro, las
inferencias se hacen del tipo ' string [] ' (el tipo de ' nombres ' ) al tipo ' T [] ' , infiriendo ' cadena ' para ' T ' . Para el
segundo parámetro, el tipeo inferencial de la expresión de flecha ' s => s.length ' hace que ' T ' se fije de manera que el
tipo inferido ' string ' pueda usarse para el parámetro ' s ' . El tipo de retorno de la expresión de flecha se puede
determinar, y las inferencias se hacen del tipo ' (s: cadena) => número ' al tipo ' (x: T) => U ' ,
deduciendo ' número ' para ' U ' . Por lo tanto, la llamada al ' mapa ' es equivalente a
En el ejemplo
función zip <S, T, U> (x: S [], y: T [], combinar: (x: S) => (y: T) => U): U [] { var len =
Math. max (longitud x, longitud y); resultado var : U [] = []; for ( var i = 0 ; i <len; i ++)
result.push (combine (x [i]) (y [i])); resultado de retorno ; }
nombres var = [ " Peter " , " Paul " , " Mary " ];
var edades = [ 7 , 9 , 12 ];
var pares = zip (nombres, edades, s => n => ({nombre: s, edad: n}));
inferencias para ' S ' , ' T ' y ' T ' en la llamada a ' zip ' se hacen como sigue: El uso de los dos
primeros parámetros, inferencias de ' cadena ' de ' S ' y ' número ' para ' T ' se hacen . Para el tercer parámetro, el tipeo
inferencial de la expresión de flecha externa hace que ' S ' se fije de manera que el tipo inferido ' string ' pueda usarse
para el parámetro ' s ' . Cuando una expresión de función se escribe inferencialmente , sus expresiones de retorno también
se escriben inferencialmente. Por lo tanto, la función de flecha interna se escribe inferencialmente, lo que hace que ' T ' se
fije de manera que el tipo inferido ' número ' pueda usarse para el parámetro ' n ' . Luego se puede determinar el tipo de
retorno de la función de flecha interna, que a su vez determina el tipo de retorno de la función devuelta desde la función
de flecha externa, y se hacen inferencias del tipo ' (s: cadena) => (n: número ) => {nombre: cadena; edad: número} ' al
tipo ' (x: S) => (y: T) => R ' , infiriendo ' {nombre: cadena; edad: número} ' para ' R ' . Por lo tanto, la llamada a ' zip ' es
equivalente a
4.15.3 Ambigüedades gramaticales
La inclusión de argumentos de tipo en la Argumentos de producción (sección 4.15 ) dan s lugar a ciertas ambigüedades en
la gramática para expresiones. Por ejemplo, la declaración
podría interpretarse como una llamada a ' f ' con dos argumentos, ' g <A ' y ' B> (7) ' . Alternativamente, podría
interpretarse como una llamada a ' f ' con un argumento, que es una llamada a una función genérica ' g ' con dos
argumentos de tipo y un argumento regular.
La ambigüedad gramatical se resuelve de la siguiente manera: en un contexto donde una posible interpretación de una
secuencia de tokens es una producción de Argumentos , si la secuencia inicial de tokens forma
una producción TypeArguments sintácticamente correcta y es seguida por un token ' ( ' , entonces la secuencia de tokens
se procesa una producción de Argumentos , y cualquier otra interpretación posible se descarta, de lo contrario, la
secuencia de tokens no se considera una producción de Argumentos .
Esta regla significa que la llamada a ' f ' anterior se interpreta como una llamada con un argumento, que es una llamada a
una función genérica ' g ' con dos argumentos de tipo y un argumento regular. Sin embargo, las declaraciones
Forma de clase {... }
clase Círculo extiende Forma { ...}
función createShape (kind: string ): Shape { if (kind === " circle " ) devuelve un nuevo Circle ();
... }
Como se mencionó anteriormente, las aserciones de tipo no se verifican en tiempo de ejecución y corresponde al
programador protegerse contra errores, por ejemplo, utilizando el operador instanceof :
4.17 Expresiones JSX
TODO: documenta las expresiones JSX .
4.18 Operadores unarios
Las subsecciones que siguen especifican las reglas de procesamiento en tiempo de compilación de los operadores
unarios. En general, si el operando de un operador unario no cumple con los requisitos establecidos, se produce un error
en tiempo de compilación y el resultado de la operación se predetermina al tipo A ny en el procesamiento posterior.
El operador unario + convenientemente se puede utilizar para conve rt un valor de cualquier tipo para la N umber tipo
primitivo :
función getValue () {...}
var n = + getValue ();
El ejemplo anterior convierte el resultado de ' getValu e () ' a un número si ISN ' bronceado umber alrea dy. El tipo inferido
para ' n ' es el tipo primitivo N umber independientemente del tipo de retorno de ' getValue ' .
4.18.3 El! operador
Los ! operador permite su operando a ser de cualquier tipo y produce un resultado de la booleana tipo primitivo .
¡Dos unarios ! operadores de secuencia se pueden usar convenientemente para convertir un valor de cualquier tipo
para la Boolean tipo primitivo :
función getValue () {...}
var b = !! getValue ();
El ejemplo anterior convierte el resultado de ' getValue () ' a un booleano si ISN ' ta Boolean ya. El tipo e inferido
para ' b ' es el tipo primitivo booleano independientemente del tipo de retorno de ' getValue ' .
var x = 5 ;
var y = typeof x; // Usar en una expresión
var z: typeof x; // Usar en una consulta de tipo
4.19 Operadores binarios
Las subsecciones que siguen especifican las reglas de procesamiento en tiempo de compilación de los operadores
binarios . En general, si los operandos de un operador binario no cumplen los requisitos establecidos, se produce un error
en tiempo de compilación y el resultado de la operación se predetermina para escribir un ny en el procesamiento
posterior. Las tablas que resumen los proces de tiempo de compilación cantar reglas para operandos de la
A ny tipo , el booleano, número, y S Tring tipos primitivos , y todos los otros tipos (la O Ther de columna en las tablas) se
proporcionan.
Booleano
S tring
O Ther
TODO: Documente el operador de exponenciación .
función getValue () {...}
var s = getValue () + "" ;
El ejemplo anterior convierte el resultado de ' getVa lue () ' en una cadena si no es ' tas tring alrea dy'. El tipo inferido
para ' s ' es el tipo primitivo S tring independientemente del tipo de retorno de ' getValue ' .
Tenga en cuenta que tipo de objeto s que contiene una o más solicitudes o construir firmas se subtipo
automáticamente s de la ' Función ' tipo de interfaz , como se describe en la sección 3.3 .
4.19.7 El || operador
El || El operador permite que los operandos sean de cualquier tipo.
prueba ? e xpr1: e xpr2
Si la expresión condicional se escribe contextualmente (sección 4.23 ) , e xpr1 y e xpr2 se escriben simultáneamente por el
mismo tipo. De lo contrario, expr1 y expr2 no se escriben contextualmente.
4.21 Operadores de asignación
Una asignación del formulario
v = expr
Una asignación compuesta del formulario.
v ?? = expr
está sujeta a los mismos requisitos , y produce un valor del mismo tipo , como la operación no compuesto
correspondiente. Además, una asignación compuesta requiere que v se clasifique como referencia (sección 4.1 ) y que el
tipo de operación no compuesta se pueda asignar al tipo de v . Tenga en cuenta que no se permite que v sea un patrón
de asignación en una asignación compuesta.
4.21.1 Asignación de Desestructuración
Una asignación de desestructuración es una operación de asignación en la que el operando de la izquierda
está estructurando un patrón de asignación como se define en la producción de AssignmentPattern en
la especificación ECMAScript 2015 .
En una expresión de asignación desestructurante, el tipo de expresión de la derecha debe ser asignable al objetivo de
asignación de la izquierda. Una expresión de tipo S se considera asignable a un objetivo de asignación V si uno de los
siguientes es verdadero:
TODO: Actualización para especificar el comportamiento cuando el elemento de asignación E es un elemento de descanso .
En una propiedad o elemento de asignación que incluye un valor predeterminado, el tipo del valor predeterminado debe
ser asignable al objetivo dado en la propiedad o elemento de asignación.
Cuando el objetivo de salida es ECMAScript 2015 o superior, las asignaciones de variables de desestructuración
permanecen sin cambios en el código JavaScript emitido. Cuando el objetivo de salida es ECMAScript 3 o 5, las
asignaciones variables de desestructuración se reescriben en series de asignaciones simples. Por ejemplo, la tarea de
desestructuración
var x = 1 ;
var y = 2 ;
[x, y] = [y, x];
var x = 1 ;
var y = 2 ;
_a = [y, x], x = _a [ 0 ], y = _a [ 1 ];
var _a;
4.23 Expresiones de tipo contextual
La verificación de tipos de una expresión se mejora en varios contextos al tener en cuenta el tipo de destino del valor
calculado por la expresión . En tales situaciones, se dice que la expresión está contextualizada por el tipo de
destino . Una expresión se escribe contextualmente en las siguientes circunstancias:
En una variable, parámetro, propiedad de enlace, elemento de enlace o declaración de miembro, una expresión de
inicializador se escribe contextualmente por
o t que tipo dado en el de declaración de tipo de anotación, en su caso, o de otro modo
o para un parámetro, el tipo proporcionado por una firma contextual (sección 4.10 ) , si existe, o de lo
contrario
o el tipo implicado por el patrón de enlace en la declaración (sección 5.2.3 ) , si existe.
I n el cuerpo de una función de declaración, la función de la expresión, función de la flecha , el método
de declaración , o de acceso Get declaración que tiene una anotación de tipo de retorno , el retorno
expresiones están contextualmente tecleado por el tipo dado en la anotación tipo de retorno.
En el cuerpo de una expresión de función o función de flecha que no tiene una anotación de tipo de retorno, si la
expresión de función o la función de flecha está contextualizada por un tipo de función con exactamente una firma
de llamada , y si esa firma de llamada no es genérica , las expresiones de retorno son contextualizado por el tipo de
retorno de esa firma de llamada.
En el cuerpo de una declaración de constructor , las expresiones de retorno se tipifican contextualmente por el
tipo de clase que lo contiene.
En el cuerpo de un descriptor de acceso get sin anotación de tipo de retorno , si existe un descriptor
de acceso coincidente y ese descriptor de acceso tiene una anotación de tipo de parámetro, las expresiones de
retorno se contextualizan según el tipo dado en la anotación de tipo de parámetro del descriptor de acceso.
En una llamada de función escrita , las expresiones de argumento se escriben contextualmente por sus
correspondientes tipos de parámetros.
En un literal de objeto contextualizado , cada expresión de valor de propiedad se escribe contextualmente por
o El tipo de propiedad con un nombre coincidente en el tipo contextual, si lo hay, o de lo contrario
o para una propiedad con nombre numérico , el tipo de índice numérico del tipo contextual, si lo hay, o de
lo contrario
o el tipo de índice de cadena del tipo contextual, si lo hay.
En una expresión literal de matriz contextualizada que no contiene elementos de propagación , una expresión de
elemento en el índice N se escribe contextualmente por
o El tipo de propiedad con el nombre numérico N en el tipo contextual, si lo hay, o de lo contrario
o El tipo de índice numérico del tipo contextual, si lo hay.
En una expresión literal de matriz contextualizada que contiene uno o más elementos extendidos, una expresión
de elemento en el índice N se escribe contextualmente por el tipo de índice numérico del tipo contextual, si lo hay.
En una expresión entre paréntesis contextualizada , la expresión contenida se escribe contextualmente por el
mismo tipo.
En una aserción de tipo , la expresión se escribe contextualmente por el tipo indicado.
En un || expresión de operador, si la expresión se escribe contextualmente, los operandos
se escriben contextualmente por el mismo tipo. De lo contrario , la expresión derecha se escribe contextualmente
por el tipo de la expresión izquierda.
En una expresión de operador condicional tipeada contextualmente , los operandos se tipean contextualmente
por el mismo tipo.
En una expresión de asignación, la expresión de la mano derecha se escribe contextualmente por el tipo de la
expresión de la mano izquierda.
En el siguiente ejemplo
interfaz EventObject {
x: número ;
y: número ;
}
interfaz EventHandlers {
mousedown ? : (event: EventObject) => void ;
mouseup ? : (event: EventObject) => void ;
mousemove ? : (event: EventObject) => void ;
}
función setEventHandlers (controladores: EventHandlers) {...}
setEventHandlers ({
mousedown: e => {startTracking (ex, ey);} ,
mouseup: e => {endTracking ();}
} ) ;
el objeto literal pasado a ' setEventHandlers ' se escribe contextualmente al tipo ' EventHandlers ' . Esto hace que las dos
asignaciones de propiedad que se escriban contextualmente a la sin nombre tipo de función ' (evento: EventObject) =>
vo ID ' , que a su vez hace que la ' e ' parámetro s en las expresiones de función flecha a ser escrito de forma automática
como ' EventObject ' .
4.24 Guardias tipo
Los protectores de tipo son patrones de expresión particulares que involucran
los operadores ' typeof ' e ' instanceof ' que hacen que los tipos de variables o parámetros se reduzcan a tipos más
específicos. Por ejemplo , en el código siguiente, el conocimiento del tipo estático de ' x ' en combinación con
un ' typeof ' cheque hace que sea seguro para estrechar el tipo de ' x ' de cadena en la primera rama del ' si ' declaración y
el número de en la segunda rama de la declaración ' if ' .
Un protector de tipo es simplemente una expresión que sigue un patrón particular. El proceso de reducir el tipo de una
variable x por una protección de tipo cuando es verdadero o falso depende de la protección de tipo de la siguiente
manera:
verdadero , o
o cuando es falso , reduce el tipo de x a T | T , donde T es el tipo de x reducido por expr cuando es
1 2 1 1
falso , y T es el tipo de x reducido por expr cuando es verdadero y luego por expr cuando es falso .
2 1 2
es verdadero , y T es el tipo de x reducido por expr cuando es falso y luego por expr cuando es
2 1 2
verdadero , o
o cuando falsa , se estrecha el tipo de x b y expr cuando falsa y luego por expr cuando falsa .
1 2
Un protector de tipo de cualquier otra forma no tiene efecto sobre el tipo de x .
En las reglas anteriores, cuando una operación de estrechamiento eliminaría todos los tipos constituyentes de un tipo de
unión, la operación no tiene efecto sobre el tipo de unión.
Tenga en cuenta que los protectores de tipo afectan solo a los tipos de variables y parámetros y no tienen efecto en los
miembros de los objetos, como las propiedades. También tenga en cuenta que es posible derrotar a un protector de tipo
llamando a una función que cambia el tipo de la variable protegida.
En el ejemplo
En el ejemplo
En el ejemplo
En el ejemplo
clase C {
datos: cadena | cadena [] ;
getData () { var data = this .data; volver typeof datos === "cadena" ? datos: data.join ( "" );
} }
el tipo de datos variable es cadena en la primera expresión condicional y string [] en la segunda expresión
condicional, y t infirió tipo de getData es cadena . Tenga en cuenta que la propiedad de datos debe copiarse en una
variable local para que la protección de tipo tenga efecto.
En el ejemplo
clase NamedItem {
nombre: cadena ;
}
function getName (obj: Object ) { return obj instanceof NamedItem? obj.name: " desconocido " ; }
el tipo de obj se estrecha a NamedItem en el primer cond i cional expresión, y el tipo inferido de la getNombre función
es la cadena .
1
5 declaraciones
Este capítulo describe la comprobación de tipos estáticos que TypeScript proporciona para las declaraciones de
JavaScript . TypeScript en sí mismo no introduce ninguna nueva construcción de sentencias, pero extiende la gramática de
las declaraciones locales para incluir declaraciones de interfaz, alias de tipo y enumeración.
5.1 bloques
Los bloques se extienden para incluir la interfaz local, el alias de tipo y las declaraciones de enumeración (las clases ya
están incluidas en la gramática ECMAScript 2015 ) .
Declaración: (Modificado) ... Tipo de declaración de interfaz Declaración de alias Declaración de enumeración
Las declaraciones de clase local, interfaz, alias de tipo y enumeración tienen un alcance de bloque, similar a las
declaraciones let y const.
5.2 Declaraciones variables
Las declaraciones variables se extienden para incluir anotaciones de tipo opcionales.
Una declaración variable es una declaración variable simple o una declaración variable desestructurante.
SimpleVariableDeclaration:
BindingI dentifier TypeAnnotation Initializer
opt opt
Cuando una declaración de variable especifica tanto una anotación de tipo como una expresión de inicializador, se
requiere que el tipo de la expresión de inicializador sea asignable (sección 3.11.4 ) al tipo dado en la anotación de tipo.
Se permiten múltiples declaraciones para el mismo nombre de variable en el mismo espacio de declaración, siempre que
cada declaración asocie el mismo tipo con la variable.
Cuando una declaración de variable tiene una anotación de tipo, es un error que esa anotación de tipo utilice
el operador typeof para hacer referencia a la variable que se declara.
A continuación se presentan algunos ejemplos de declaraciones de variables simples y sus tipos asociados.
var a; // cualquier
var b: número ; // número
var c = 1 ; // número
var d = {x: 1 , y: "hola" }; // {x: número; y: cadena; }
var e: any = "prueba" ; // alguna
Se permite lo siguiente porque todas las declaraciones de la variable única 'x' asocian el mismo tipo (Número) con 'x'.
var x = 1 ;
var x: número ;
if (x == 1 ) { var x = 2 ; }
En el siguiente ejemplo, las cinco variables son del mismo tipo e, ' {x: número; y: número; } ' .
Punto de interfaz {x: número ; y: número ; }
var a = {x: 0 , y: < número > indefinido};
var b: Punto = {x: 0 , y: indefinido};
var c = <Punto> {x: 0 , y: indefinido};
var d: {x: número ; y: número ; } = {x: 0 , y: indefinido};
var e = <{x: número ; y: número ; }> {x: 0 , y: indefinido};
DestructuringVariableDeclaration:
BindingPattern TypeAnnotation Initializer
opt
El tipo T asociado con una declaración de variable de desestructuración se determina de la siguiente manera:
Sea S el tipo asociado con la declaración de variable de desestructuración , la propiedad de enlace o el elemento
de enlace que contiene inmediatamente .
Si S es cualquier tipo:
o Si el b ncontrar p ROPIEDAD especifica un inicializador expresión , T es el tipo de que
inicializador expresión .
o De lo contrario, T es cualquier tipo.
Sea P el nombre de propiedad especificado en la propiedad de enlace.
Si S tiene una propiedad aparente con el nombre P , T es el tipo de esa propiedad.
De lo contrario, si S tiene una firma de índice numérico y P es un nombre numérico , T es el tipo de firma de
índice numérico.
De lo contrario, si S tiene una firma de índice de cadena, T es el tipo de firma de índice de cadena.
De lo contrario, no se asocia ningún tipo con la propiedad de enlace y se produce un error.
Sea S el tipo asociado con la declaración de variable de desestructuración , la propiedad de enlace o el elemento
de enlace que contiene inmediatamente .
Si S es cualquier tipo:
o Si el b ncontrar elemento especifica un inicializador expresión , T es el tipo de que inicializador expresión .
o De lo contrario, T es cualquier tipo.
Si S no es un tipo de tipo matriz (sección 3.3.2 ) , no se asocia ningún tipo con la propiedad de enlace y se
produce un error.
Si el elemento de unión es un elemento de apoyo , T es un tipo de matriz con un tipo de elemento E , donde E es
el tipo de la firma índice numérico de S .
De lo contrario, si S es una tupla -como tipo (sección 3.3.3 ) :
o Sea N el índice basado en cero del elemento de enlace en el patrón de enlace de la matriz.
o Si S tiene una propiedad con el nombre numérico N , T es el tipo de esa propiedad.
o De lo contrario, no se asocia ningún tipo con el elemento de enlace y se produce un error.
De lo contrario, si S tiene una firma de índice numérico, T es el tipo de firma de índice numérico.
De lo contrario, no se asocia ningún tipo con el elemento de enlace y se produce un error.
TODO: Actualice las reglas para reflejar una mejor verificación de la desestructuración con inicializadores literales .
W gallina el objetivo de producción es ECMAScript 2015 o superior , a excepción de la eliminación de la anotación de tipo
opcional, desestructuración variables declaraciones permanecen sin cambios en el código JavaScript emitida.
T él '_a' y variables temporales '' _b existen para asegurar la asignada expresión se evalúa sólo una vez , y la expresión
'vacío 0' simplemente denota el valor de JavaScript 'indefinido'.
5.2.3 Tipo implícito
Una variable, parámetro, propiedad de enlace o declaración de elemento de enlace que especifica que un patrón de
enlace tiene un tipo implícito que se determina de la siguiente manera:
Si la declaración especifica un patrón de enlace de objeto, el tipo implícito es un tipo de objeto con un conjunto
de propiedades correspondientes a las declaraciones de propiedades de enlace especificadas . El tipo de cada
propiedad es el tipo implícito en su declaración de propiedad vinculante, y una propiedad es opcional cuando su
declaración de propiedad vinculante especifica una expresión inicializadora.
Si la declaración especifica un patrón de enlace de matriz sin un elemento de descanso , el tipo implícito es un
tipo de tupla con elementos correspondientes a las declaraciones de elementos de enlace especificados . El tipo de
cada elemento es el tipo implícito en su declaración de elemento vinculante.
Si la declaración especifica un patrón de enlace de matriz con un elemento de descanso, el tipo implícito es un
tipo de matriz con un tipo de elemento de Any.
En el ejemplo
El tipo implícito del patrón de enlace en el parámetro de la función es '{a: any; b ?: cuerda; c ?: número; } '. Dado que el
parámetro no tiene anotaciones de tipo , este se convierte en el tipo del parámetro.
En el ejemplo
var [a, b, c] = [ 1 , "hola" , verdadero ];
la expresión de inicializador literal de matriz se escribe contextualmente por el tipo implícito del patrón de
enlace, específicamente el tipo de tupla '[cualquiera, cualquiera, cualquiera]'. Debido a que el tipo contextual es un tipo de
tupla, el tipo resultante del literal de matriz es el tipo de tupla '[número, cadena, booleano]', y la declaración de
desestructuración da así el número de tipo, cadena y booleano a a, b y c respectivamente.
DestructuringLexicalBinding :
BindingPattern TypeAnnotation Initializer
opt opt
5.5 Para declaraciones
Las declaraciones de variables en ' para ' declaración s se extienden en la misma forma que las declaraciones de variables
en los estados variables (sección 5.2 ).
5.6 Declaraciones for-in
En una declaración ' for-in ' del formulario
para la declaración ( v en expr )
v debe ser una expresión clasificada como una referencia de tipo Any o el tipo primitivo String, y expr debe ser una
expresión de tipo Any, un tipo de objeto o un tipo de parámetro de tipo.
En una declaración ' for-in ' del formulario
para ( var v en expr ) s tatement
v debe ser una declaración de variable sin una anotación de tipo que declare una variable de tipo Any , y expr debe ser
una expresión de tipo Any, un tipo de objeto o un tipo de parámetro de tipo.
5.7 Declaraciones for-of
TODO: documentar declaraciones for-of .
5.8 Continuar declaraciones
Se requiere que una instrucción ' continue ' esté anidada, directa o indirectamente (pero no cruzando los límites de la
función), con una instrucción de iteración ( ' do ' , ' while ' , ' for ' o ' for-in ' ). W uando un ' continuará ' declaración
incluye una etiqueta de destino, esa etiqueta de destino debe aparecer en el conjunto de etiquetas de una
envolvente (pero no cruzar los límites de la función) comunicado iteración.
5.9 Declaraciones de ruptura
Un ' descanso ' se requiere una declaración para ser anidado, (cruce pero no límites de función), directa o indirectamente,
dentro de una iteración ( ' hacer ' , ' mientras que ' , ' para ' , o ' for-in ' ) o ' interruptor ' declaración . Cuando
una declaración de ' interrupción ' incluye una etiqueta de destino, esa etiqueta de destino debe aparecer en el conjunto
de etiquetas de una declaración de cierre (pero no cruzando límites de función).
5.10 Declaraciones de devolución
Es un error que ocurra una declaración ' return ' fuera del cuerpo de una función. Específicamente, las declaraciones
de ' retorno ' no están permitidas a nivel global o en los cuerpos de espacios de nombres .
Un ' r eturn ' declaración sin una expresión de retorno s el valor ' indefinido ' y está permitido en el cuerpo de cualquier
función, independientemente del tipo de retorno de la función.
Cuando una declaración de ' retorno ' incluye una expresión , si la función que contiene incluye una anotación de tipo de
retorno, la expresión de retorno se tipea contextualmente (sección 4.23 ) por ese tipo de retorno y debe ser de un tipo
que se pueda asignar al tipo de retorno. De lo contrario, si la función que contiene se escribe contextualmente por un
tipo T , Expr se escribe contextualmente por el tipo de retorno de T.
En una implementación de función sin una anotación de tipo de retorno, el tipo de retorno se infiere de las declaraciones
de ' retorno ' en el cuerpo de la función, como se describe en la sección 6.3 .
En el ejemplo
la expresión de flecha en la declaración ' return ' está contextualizada por el tipo de retorno de ' f ' , dando así el
tipo ' string ' a ' s ' .
5.11 Con declaraciones
T se de la ' con ' comunicado a máquina de escribir es un error , como es el caso en ECMAScript 5 ' modo estricto
s . Además, dentro del cuerpo de un ' con ' declaración , mecanografiado considera cada identificador se producen en una
expresión (sección 4.3 ) para ser de la Cualquier tipo independientemente de su tipo declarado. Debido a que
la instrucción ' with ' pone un conjunto de identificadores estáticamente desconocidos en el alcance delante de los que
están conocidos estáticamente, no es posible asignar significativamente un tipo estático a ningún identificador.
5.12 Cambiar declaraciones
En una declaración ' switch ' , cada expresión ' case ' debe ser de un tipo que se pueda asignar ao desde (sección 3.11.4 )
el tipo de la expresión ' switch ' .
5.13 Declaraciones de lanzamiento
La expresión especificada en una declaración ' throw ' puede ser de cualquier tipo.
5.14 Intentar declaraciones
T que la variable introducida por un ' captura ' cláusula de un ' probar ' declaración es siempre del tipo Any. No es posible
incluir una anotación de tipo en una cláusula ' catch ' .
1
6 6 Las funciones
Una declaración de función introduce un valor con nombre de un tipo de función en el espacio de declaración que
contiene . El BindingIdentifier es opcional solamente cuando la declaración de la función se produce en una
exportación declaración predeterminado (sección 11.3.4.2 ).
Las declaraciones de funciones que especifican un cuerpo se denominan implementaciones de funciones y las
declaraciones de funciones sin un cuerpo se denominan sobrecargas de funciones . Es posible especificar
múltiples sobrecargas para la misma función (es decir, para el mismo nombre en el mismo espacio de declaración) ,
pero una función puede tener como máximo una implementación. Todas las declaraciones para la misma función deben
especificar el mismo conjunto de modificadores (es decir, la misma combinación
de declarar , exportar y predeterminado ).
Cuando una función tiene declaraciones de sobrecarga, las sobrecargas determinan las firmas de llamada del tipo dado al
objeto de función y la firma de implementación de la función (si la hay) debe ser asignable a ese tipo. De lo contrario, la
implementación de la función misma determina la firma de la llamada.
Cuando una función tiene sobrecargas y una implementación, las sobrecargas deben preceder a la implementación y
todas las declaraciones deben ser consecutivas sin elementos gramaticales intermedios.
6.2 Sobrecargas de funciones
Las sobrecargas de funciones permiten una especificación más precisa de los patrones de invocación soportados por una
función que la que es posible con una sola firma. El procesamiento en tiempo de compilación de una llamada a una
función sobrecargada elige la mejor sobrecarga candidata para los argumentos particulares y el tipo de retorno de esa
sobrecarga se convierte en el tipo de resultado de la expresión de llamada de función. Por lo tanto, el uso de
sobrecargas que es posible estáticamente describir la manera en que una función de ' tipo de retorno s varía en función
de sus argumentos. La resolución de sobrecarga en las llamadas a funciones se describe más adelante en la sección 4.15 .
Las sobrecargas de funciones son puramente una construcción en tiempo de compilación. No tienen impacto en el
JavaScript emitido y, por lo tanto, no tienen costo de tiempo de ejecución.
La lista de parámetros de una sobrecarga de funciones no puede especificar valores predeterminados para los
parámetros. En otras palabras, una sobrecarga puede usar solo el ? forma al especificar parámetros opcionales.
función attr (nombre: cadena ): cadena ;
función attr (nombre: cadena , valor: cadena ): Accesor;
función attr (mapa: cualquiera ): Accesor;
la función attr (nameOrMap: ninguna , valor ? : string ): ninguna { si (nameOrMap && typeof nameOrMap
=== " string " ) { // manipulador cadena caso } demás { // h andle mapa caso } }
Tenga en cuenta que cada sobrecarga y la implementación final especifican el mismo identificador. El tipo de la variable
local ' attr ' introducida por esta declaración es
var attr: {
(nombre: cadena ): cadena ;
(nombre: cadena , valor: cadena ): Accesor;
(mapa: cualquiera ): Accesor;
} ;
Tenga en cuenta que la firma de la implementación de la función real no está incluida en el tipo.
6.3 Implementaciones de funciones
Se dice que una implementación de función sin una anotación de tipo de retorno es una función tipada
implícitamente . El tipo de retorno de una función implícita mecanografiado f se infiere de su cuerpo de la función como
sigue:
Si no hay declaraciones de retorno con expresiones en f ' s cuerpo de la función, el tipo de retorno inferido es
Vacío.
De lo contrario, si f ' cuerpo de la función s referencia directamente f o referencias funciones que a través de esta
misma referencia análisis tecleó cualquier implícitamente f , el tipo de retorno inferida es cualquier.
De lo contrario, si f es una expresión de función contextualizada (sección 4.10 ), el tipo de retorno inferido es el
tipo de unión (sección 3.4 ) de los tipos de expresiones de declaración de retorno en el cuerpo de la función,
ignorando las declaraciones de retorno sin expresiones.
De lo contrario, el tipo de retorno inferido es el primero de los tipos de expresiones de declaración de retorno en
el cuerpo de la función que es un supertipo (sección 3.11.3 ) de cada uno de los otros, ignorando las declaraciones
de retorno sin expresiones. Se produce un error en tiempo de compilación si ninguna expresión de declaración de
retorno tiene un tipo que sea un supertipo de cada una de las otras.
En el ejemplo
el tipo de retorno inferido para ' f ' y ' g ' es Cualquiera porque las funciones hacen referencia a sí mismas a través de un
ciclo sin anotaciones de tipo de retorno. Agregar un tipo de retorno explícito ' número ' a cualquiera de los dos rompe el
ciclo y hace que el tipo de retorno ' número ' se infiera para el otro.
Una función de tipo explícito de cuyo retorno Tipo de ISN ' t el Vacío tipo, el Cualquier tipo o un tipo de unión que
contiene el Vacío o cualquier tipo como constituyente debe tener al menos una instrucción de retorno en algún lugar de
su cuerpo. Una excepción a esta regla es si la implementación de la función consiste en una sola declaración ' throw ' .
En la firma de la implementación de una función, un parámetro puede marcarse como opcional siguiéndolo con un
inicializador. Cuando una declaración de parámetro incluye tanto una anotación de tipo como un inicializador, la
expresión de inicializador se tipea contextualmente (sección 4.23 ) por el tipo indicado y debe ser asignable al tipo
indicado, o de lo contrario se produce un error en tiempo de compilación. Cuando una declaración de parámetro no tiene
anotaciones de tipo pero incluye un inicializador, el tipo del parámetro es la forma ampliada (sección 3.12 ) del tipo de la
expresión del inicializador.
Las expresiones de inicialización se evalúan en el ámbito del cuerpo de la función, pero no se les permite hacer referencia
a variables locales y solo se les permite acceder a los parámetros que se declaran a la izquierda del parámetro que
inicializan , a menos que la referencia de parámetro ocurra en una expresión de función anidada .
Cuando el objetivo de salida es ECMAScript 3 o 5, para cada parámetro con un inicializador, se incluye una declaración
que sustituye el valor predeterminado por un argumento omitido en el JavaScript generado, como se describe en la
sección 6.6 . El ejemplo
En el ejemplo
var x = 1;
función f (a = x) { var x = " hola " ; }
la variable local ' x ' está dentro del alcance en el inicializador de parámetros (ocultando así la ' x ' externa ), pero es un
error hacer referencia a ella porque siempre estará sin inicializar en el momento en que se evalúa el inicializador de
parámetros .
El tipo de local introducido en una declaración de parámetro de desestructuración se determina de la misma manera que
un local introducido mediante una declaración de variable de desestructuración, excepto que el tipo T asociado con una
declaración de parámetro de desestructuración se determina de la siguiente manera:
El ejemplo
Las declaraciones de parámetros de desestructuración no permiten anotaciones de tipo en los patrones de enlace
individuales, ya que tales anotaciones entrarían en conflicto con el significado ya establecido de dos puntos en literales de
objeto. Las anotaciones de tipo deben escribirse en la declaración de parámetros de nivel superior. Por ejemplo
interfaz DrawTextInfo {
text ?: string ;
ubicación ?: [ número , número ];
negrita: booleano ;
}
función drawText ({texto, ubicación: [x, y], negrita}: DrawTextInfo) { // Dibujar texto }
6.5 Funciones genéricas
La implementación de una función puede incluir parámetros de tipo en su firma (sección 3.9.2.1 ) y luego se
denomina función genérica . Los parámetros de tipo proporcionan un mecanismo para expresar relaciones entre
parámetros y tipos de retorno en operaciones de llamada. Los parámetros de tipo no tienen representación en tiempo de
ejecución; son puramente una construcción en tiempo de compilación.
Los parámetros de tipo declarados en la firma de una implementación de función están dentro del alcance de la firma y
el cuerpo de esa implementación de función.
Tenga en cuenta que las ' x ' y ' Y ' parámetros son conocidos por ser subtipos de los contras Traint ' Comparable ' y por lo
tanto tener un ' compareTo ' miembro. Esto se describe más adelante en la sección 3.6.1 .
Los argumentos de tipo de una llamada a una función genérica pueden especificarse explícitamente en una operación de
llamada o, cuando sea posible, inferirse (sección 4.15.2 ) de los tipos de argumentos regulares en la llamada. En el ejemplo
El argumento de tipo para ' comparar ' se infiere automáticamente que es el tipo de Cadena porque los dos argumentos
son cadenas.
6.6 Codigo de GENERACION
Una declaración de función genera código JavaScript que es equivalente a:
function <FunctionName> (<FunctionParameters>) {
<DefaultValueAssignments>
<FunctionStatements>
}
Función Param eter s es una lista separada por comas de la función de ' nombres de los parámetros s.
DefaultValueAssignments es una secuencia de asignaciones de valor de propiedad predeterminadas, una para cada
parámetro con un valor predeterminado, en el orden en que se declaran, del formulario
6.8 Funciones asincrónicas
TODO: documenta funciones asincrónicas .
6.9 Funciones de protección de tipo
TODO: funciones de protección de tipo de documento , incluidos los predicados de este tipo .
1
7 interfaces
Las interfaces proporcionan la capacidad de nombrar y parametrizar tipos de objetos y componer los tipos de objetos
nombrados existentes en otros nuevos.
Las interfaces no tienen representación en tiempo de ejecución: son puramente una construcción en tiempo de
compilación. Las interfaces son particularmente útiles para documentar y validar la forma requerida de las propiedades,
los objetos pasados como parámetros y los objetos devueltos por las funciones.
Dado que TypeScript tiene un sistema de tipo estructural, un tipo de interfaz con un conjunto particular de miembros se
considera idéntico y puede ser sustituido por otro tipo de interfaz o tipo de objeto literal con un conjunto idéntico de
miembros (ver sección 3.11.2 ) .
Las declaraciones de clase pueden hacer referencia a interfaces en su cláusula de implementos para validar que
proporcionan una implementación de las interfaces.
7.1 Declaraciones de interfaz
Una declaración de interfaz declara un tipo de interfaz .
InterfaceDeclaration:
interfaz BindingI dentifier TypeParameters InterfaceExtendsClause ObjectType
opt opt
InterfaceExtendsClause:
extiende ClassOrInterfaceTypeList
ClassOrInterfaceTypeList:
ClassOrInterfaceType
ClassOrInterfaceTypeList , ClassOrInterfaceType
ClassOrInterfaceType:
TypeReference
Una declaración de interfaz introduce un tipo con nombre (sección 3.7 ) en el espacio de declaración que lo
contiene. El dentificador BindingI de una declaración de interfaz puede no ser uno de los nombres de tipo predefinidos
(sección 3.8.1 ).
Opcionalmente, una interfaz puede tener parámetros de tipo (sección 3.6.1 ) que sirven como marcadores de posición
para los tipos reales que se proporcionarán cuando se hace referencia a la interfaz en referencias de tipo. Una interfaz con
parámetros de tipo se denomina interfaz genérica . Los parámetros de tipo de una declaración de interfaz genérica están
dentro del alcance de toda la declaración y se pueden hacer referencia en el cuerpo InterfaceExtendsClause y ObjectType .
Una interfaz puede heredar de cero o más tipos base que se especifican en InterfaceExtendsClause . Los tipos base deben
ser referencias de tipo a clases o tipos de interfaz.
Una interfaz tiene los miembros especificados en el ObjectType de su declaración y además hereda todos los de base de
tipo a los miembros que aren ' t ocultos por declaraciones en el inte rface:
Las siguientes restricciones deben cumplirse mediante una declaración de interfaz o, de lo contrario, se produce un error
en tiempo de compilación :
Una declaración de interfaz no puede, directa o indirectamente, especificar un tipo base que se origina en la
misma declaración. En otras palabras, una interfaz no puede, directa o indirectamente, ser un tipo base de sí misma,
independientemente de los argumentos de tipo.
Una interfaz no puede declarar una propiedad con el mismo nombre que una propiedad privada o
protegida heredada .
Las propiedades heredadas con el mismo nombre deben ser idénticas (sección 3.11.2 ).
Todas las propiedades de la interfaz deben satisfacer las restricciones implícitas en las firmas de índice de la
interfaz como se especifica en la sección 3.9.4 .
El (sección de este tipo 3.6.3 ) de la declarada interfaz debe ser asignable (sección 3.11.4 ) a cada una de las
referencias de tipo base.
Se permite que una interfaz herede miembros idénticos de múltiples tipos base y en ese caso solo contendrá una
aparición de cada miembro en particular .
A continuación se muestra un ejemplo de dos interfaces que contienen propiedades con el mismo nombre pero diferentes
tipos:
la interfaz MoverShaker extiende Mover, Shaker {
getStatus (): {speed: number ; frecuencia: número ; };
}
Dado que los tipos de función y constructor son solo tipos de objeto que contienen firmas de llamada y construcción, las
interfaces se pueden usar para declarar tipos de función y constructor con nombre. Por ejemplo:
Esto declara que el tipo ' StringComparer ' es un tipo de función que toma dos cadenas y devuelve un número.
7.2 Declaración de fusión
Las interfaces son " abiertas " y las declaraciones de interfaz con el mismo nombre calificado relativo a una raíz común
(como se define en la sección 2.3 ) contribuyen a una única interfaz.
Cuando una interfaz genérica tiene múltiples declaraciones, todas las declaraciones deben tener listas de parámetros de
tipo idénticos, es decir, nombres de parámetros de tipo idénticos con restricciones idénticas en el mismo orden.
En una interfaz con múltiples declaraciones, t que se extiende cláusulas se fusionan en un único conjunto de tipos de
base y de los cuerpos de las declaraciones de interfaz se fusionan en un solo tipo de objeto. La fusión de declaraciones
produce un orden de declaración que corresponde a anteponer los miembros de cada declaración de interfaz ,
en el orden en que se escriben los miembros , a la lista combinada de miembros en el orden de las declaraciones de
interfaz. Por lo tanto, los miembros declarados en la última declaración de interfaz aparecerán primero en el orden de
declaración del tipo combinado.
Documento de interfaz {
createElement (tagName: any ): Element;
}
Documento de interfaz {
createElement (tagName: string ): HTMLElement;
}
Documento de interfaz {
createElement (tagName: " div " ): HTMLDivElement;
createElement (tagName: " span " ): HTMLSpanElement;
createElement (tagName: " canvas " ): HTMLCanvasElement;
}
Documento de interfaz {
createElement (tagName: " div " ): HTMLDivElement;
createElement (tagName: " span " ): HTMLSpanElement;
createElement (tagName: " canvas " ): HTMLCanvasElement;
createElement (tagName: string ): HTMLElement;
createElement (tagName: any ): Elemento;
}
Tenga en cuenta que los miembros de la última declaración de interfaz aparecen primero en la declaración
fusionada. También tenga en cuenta que se conserva el orden relativo de los miembros declarados en el mismo cuerpo de
interfaz.
Control de clase { estado privado : cualquiera ; }
interfaz SelectableControl extiende Control {
select (): void ;
}
El botón de clase extiende el control {
select () {}
}
class TextBox extiende Control {
select () { }
}
clase Imagen extiende Control {
}
ubicación de clase {
select () {}
}
1
8 Clases
TypeScript amplía las clases de JavaScript para incluir parámetros de tipo, implementa cláusulas, modificadores de
accesibilidad, declaraciones de variables miembro y declaraciones de propiedades de parámetros en constructores.
Una declaración de clase introduce un tipo con nombre (el tipo de clase) y un valor con nombre (la función de constructor)
en el espacio de declaración que lo contiene. El tipo de clase se forma a partir de los miembros de instancia declarados en
el cuerpo de la clase y los miembros de instancia heredados de la clase base . La función de constructor recibe un tipo
anónimo formado por la declaración de constructor , las declaraciones de miembro estático en el cuerpo de la clase y los
miembros estáticos heredados de la clase base . La función constructora se inicializa y devuelve una instancia del tipo de
clase.
El dentificador BindingI de una declaración de clase puede no ser uno de los nombres de tipo predefinidos
(sección 3.8.1 ). El BindingIdentifier es opcional solamente cuando la declaración de clase se produce en una
exportación de declaración por defecto (sección 11.3.4.2 ).
Opcionalmente, una clase puede tener parámetros de tipo (sección 3.6.1 ) que sirven como marcadores de posición para
los tipos reales que se proporcionarán cuando se hace referencia a la clase en referencias de tipo. Una clase con
parámetros de tipo se llama clase genérica . Los parámetros de tipo de una declaración de clase genérica están dentro
del alcance de la declaración completa y pueden ser referenciados en ClassHeritage y ClassBody .
class Point { constructor ( public x: number , public y: number ) {} public length ()
{ return Math.sqrt ( this .x * this .x + this .y * this .y); } origen estático = nuevo punto
( 0 , 0 ); }
T se denomina valor de 'Punto' es una función constructora cuyo tipo corresponde a la declaración
El contexto en el que se hace referencia a una clase distingue entre el tipo de clase y la función constructora. Por ejemplo,
en la declaración de asignación
var p : Punto = nuevo punto ( 10 , 20 );
el identificador ' Punto ' en la anotación de tipo se refiere al tipo de clase , mientras que el identificador ' Punto ' en
la nueva expresión se refiere al objeto de función constructor.
ClassExtendsClause:
extiende ClassType
ClassType :
TypeReference
ImplementsClause:
implementa ClassOrInterfaceTypeList
Las siguientes restricciones deben ser satisfechas por la especificación de herencia de clase o, de lo contrario, se produce
un error en tiempo de compilación:
clase A {a: número ; }
espacio de nombres Foo { var A = 1; la clase B extiende A {b: cadena ; } }
Cuando se evaluó como una expresión, la referencia de tipo ' A ' en el extiende cláusula doesn ' t referencia a la función
constructor de la clase de ' A ' (en lugar se hace referencia a la variable local ' A ' ).
La única situación en la que la dos última restricción es superior son violados es cuando una clase anula uno o más
miembros de la clase de base con nuevos miembros incompatibles.
Tenga en cuenta que debido a mecanografiado tiene un sistema de tipo estructural, una clase doesn ' t necesidad de
indicar explícitamente que implementa una interfaz es suficiente para que la clase contiene simplemente el conjunto
apropiado de instancia miembros. La cláusula implements de una clase proporciona un mecanismo para afirmar y validar
que la clase contiene los conjuntos apropiados de miembros de instancia , pero de lo contrario no tiene ningún efecto
sobre el tipo de clase.
8.1.2 Cuerpo de clase
El cuerpo de la clase consta de cero o más declaraciones de constructor o miembro. Las declaraciones no están permitidas
en el cuerpo de una clase; deben colocarse en el constructor o en los miembros .
El cuerpo de la clase puede contener opcionalmente una única declaración de constructor . Las declaraciones de
constructor se describen en la sección 8.3 .
Las declaraciones de miembros se utilizan para declarar instancias y miembros estáticos de la clase. Las declaraciones de
miembros de propiedades se describen en la sección 8.4 y las declaraciones de miembros de índice se describen en la
sección 8.5 .
8.2 Miembros
Los miembros de una clase consisten en los miembros introducidos a través de declaraciones de miembros en el cuerpo
de la clase y los miembros heredados de la clase base .
Instancia m brasas son miembros de la clase tipo (sección 8.2.4 ) y su asociado este tipo . Dentro de los constructores, las
funciones de miembro de instancia y los accesores de miembro de instancia, el tipo de este es este tipo (sección 3.6.3 )
de la clase .
Los miembros estáticos se declaran utilizando el modificador estático y son miembros del tipo de función de
constructor (sección 8.2.5 ) . Dentro de las funciones miembro estáticas y accesos de miembros estáticos, el tipo
de este i es la función constructora típ correo .
8.2.2 Accesibilidad
Las propiedades tienen acceso público , privado o protegido . El valor predeterminado es la accesibilidad pública,
pero las declaraciones de los miembros de la propiedad pueden incluir
un modificador público , privado o protegido para especificar explícitamente la accesibilidad deseada.
P rivate propiedad miembros sólo se puede acceder dentro del IR clase declarar . En concreto, un me privadas mber M
que declaran en una clase C se puede acceder solamente dentro del cuerpo de la clase de C .
Solo se puede acceder a los miembros de propiedad protegidos dentro de la clase de declaración de IR y las clases
derivadas de la clase de declaración de IR , y se debe acceder a un miembro de propiedad de instancia protegida a través
de una instancia de la clase adjunta o una subclase de la misma . Específicamente, un miembro protegido M declarado en
una clase C puede accederse solamente dentro del cuerpo de la clase de C o el cuerpo de la clase de una clase derivada
de C . Además, cuando un miembro de instancia protegido M se accede en un acceso a la propiedad E . M dentro del
cuerpo de una clase D , se requiere que el tipo de E sea D o un tipo que directa o indirectamente tenga D como tipo
base , independientemente de los argumentos de tipo.
La accesibilidad privada y protegida se aplica solo en tiempo de compilación y no sirve más que como una indicación de
intención . Dado que JavaScript no proporciona ningún mecanismo para crear propiedades privadas y protegidas en un
objeto, no es posible aplicar los modificadores privados y protegidos en el código dinámico en tiempo de ejecución. Por
ejemplo, la accesibilidad privada y protegida puede ser derrotado por el cambio de un objeto ' tipo estático s a Cualquiera
y acceder al miembro de forma dinámica.
En la clase ' A ' , los accesos a ' x ' están permitidos porque ' x ' está declarado en ' A ' , y los accesos a ' y ' están
permitidos porque ambos tienen lugar a través de una instancia de ' A ' o un tipo derivado de ' A ' . En la clase de ' B ' ,
acceso a ' x ' no está permitido, y el primer acceso a ' y ' i S un error porque se lleva a cabo a través de una instancia
de ' A ' , que no se deriva de la clase envolvente ' B ' .
8.2.3 Herencia y anulación
Un derivado clase hereda todos los miembros de su clase base que doesn ' t anulación . La herencia significa que una
clase derivada contiene implícitamente todos los miembros no anulados de la clase base. O ólo pública y protegida la
propiedad miembro de s se puede anular.
Una propiedad miembro en una clase derivada se dice para anular una propiedad miembro en una clase base cuando la
clase derivada propiedad miembro tiene el mismo nombre y tipo (instancia o estática) como la clase
base propiedad miembro. El tipo de una imperiosa propiedad miembro debe ser asignable (sección 3.11.4 ) para el tipo de
la anulado propiedad miembro, o de lo contrario se produce un error de tiempo de compilación.
Las funciones de miembro de instancia de clase base pueden ser anuladas por funciones de miembro de instancia de clase
derivadas, pero no por otros tipos de miembros.
Las variables miembro y los accesos de la instancia de cl ass base pueden ser anulados por las variables y los accesos
miembros de la instancia de clase derivada , pero no por otros tipos de miembros.
8.2.4 Tipos de clase
Una declaración de clase declara un nuevo tipo con nombre (sección 3.7 ) llamado tipo de clase. Dentro de las funciones
de constructor y miembro de instancia de una clase, el tipo de este es el this-type (sección 3.6.3 ) de ese tipo de
clase . El tipo de clase tiene los siguientes miembros:
Todos los miembros de propiedad de instancia (incluidos los que son privados o protegidos ) de una clase deben
satisfacer las restricciones implícitas por los miembros de índice de la clase como se especifica en la sección 3.9.4 .
En el ejemplo
clase A { public x: number ; public f () {} public g
(a: any ) { return undefined; } estático s: cadena ; }
la clase B extiende A { public y: number ; public g (b: boolean ) { return false; } }
interfaz A {
x: número ;
f: () => vacío ;
g: (a: cualquiera ) => cualquiera ;
}
interfaz B {
x: número ;
y: número ;
f: () => vacío ;
g: (b: boolean ) => boolean ;
}
Tenga en cuenta que las declaraciones estáticas en una clase no contribuyen al tipo de clase; más bien, las declaraciones
estáticas introducen propiedades en el objeto de función del constructor. También tenga en cuenta que la declaración
de ' g ' en ' B ' anula el miembro heredado de ' A ' .
8.2.5 Tipos de funciones de constructor
El tipo de la función constructora introducida por una declaración de clase se denomina tipo de función constructora. El
tipo de función constructor tiene los siguientes miembros:
Si la clase no contiene ninguna declaración de constructor y no tiene una clase base, una firma de construcción
única sin parámetros, que tiene los mismos parámetros de tipo que la clase (si existe) y que devuelve una
instanciación del tipo de clase con esos parámetros de tipo pasados como argumentos de tipo.
Si la clase no contiene ninguna declaración de constructor y tiene una clase base , un conjunto de firmas de
construcción con los mismos parámetros que los del tipo de función del constructor de la clase base después de la
sustitución de los parámetros de tipo con los argumentos de tipo especificados en la referencia de tipo de clase de
base , todos tener los mismos parámetros de tipo que la clase (si existe) y devolver una instancia del tipo de clase
con esos parámetros de tipo pasados como argumentos de tipo .
Si la clase contiene una declaración de constructor sin sobrecargas, una firma de construcción con la lista de
parámetros de la implementación del constructor , que tiene los mismos parámetros de tipo que la clase (si existe) y
devuelve una instanciación del tipo de clase con esos parámetros de tipo pasados como tipo argumentos .
Si la clase contiene una declaración de constructor con sobrecargas, un conjunto de firmas de
construcciones con las listas de parámetros de las sobrecargas , todas con los mismos parámetros de tipo que la
clase (si existe) y devolviendo una instanciación del tipo de clase con esos parámetros de tipo pasados como Escribe
argumentos .
Una propiedad para cada declaración de variable miembro estática en el cuerpo de la clase.
Una propiedad de un tipo de función para cada declaración de función miembro estática en el cuerpo de la clase.
Una propiedad para cada declaración de acceso de miembro estático con un nombre único en el cuerpo de la
clase.
Una propiedad llamada ' prototipo ' , cuyo tipo es una instanciación del tipo de clase con el tipo Any suministrado
como argumento de tipo para cada parámetro de tipo.
Todas las propiedades del tipo de función del constructor de la clase base que no se anulan en la clase.
Cada clase contiene automáticamente un miembro de propiedad estático llamado ' prototipo ' , cuyo tipo es la clase que
contiene con el tipo Any sustituido por cada parámetro de tipo.
El ejemplo
var Par: { nuevo <T1, T2> (elemento1: T1, elemento2: T2): Par <T1, T2>; }
8.3 Declaraciones de constructor
Una declaración de constructor declara la función de constructor de una clase.
ConstructorDeclaration:
AccessibilityModifier constructor ( ParameterList ) { FunctionBody } AccessibilityModifier constructor (
opt opt opt
ParameterList ) ;
opt
Declaraciones del constructor que especifican un cuerpo se llaman constructor implementaciones y declaraciones del
constructor sin un cuerpo que se llama constructor sobrecargas . Es posible especificar múltiples sobrecargas de
constructor en una clase, pero una clase puede tener como máximo una implementación de constructor. Todas
las declaraciones de constructor en una clase deben especificar el mismo conjunto de modificadores. Solo los
constructores públicos son compatibles y los constructores privados o protegidos producen un error.
En una clase sin declaración de constructor, se proporciona un constructor automático, como se describe en la
sección 8.3.3 .
Cuando una clase tiene sobrecargas de constructor, las sobrecargas determinan las firmas de construcción del tipo dado
al objeto de función de constructor, y la firma de implementación del constructor (si la hay) debe ser asignable a ese
tipo. De lo contrario, la propia implementación del constructor determina la firma de la construcción. Esto es exactamente
paralelo a la forma en que se procesan las sobrecargas en una declaración de función (sección 6.2 ).
Los parámetros de tipo de una clase genérica están dentro del alcance y son accesibles en una declaración de constructor.
8.3.1 Parámetros de constructor
Similar a las funciones, solo la implementación del constructor (y no las sobrecargas del constructor) puede
especificar expresiones de valor por defecto para parámetros opcionales. Es un error en tiempo de compilación que tales
expresiones de valor predeterminado hagan referencia a esto . Cuando el objetivo de salida es ECMAScript 3 o 5,
para cada parámetro con un valor predeterminado , se incluye una declaración que sustituye el valor predeterminado por
un argumento omitido en el JavaScript generado para la función de constructor.
Una declaración de propiedad de parámetro puede declarar una opción al parámetro (al incluir un signo de
interrogación o un valor predeterminado), pero la propiedad introducida por una declaración siempre se considera una
propiedad requerida (sección 3.3.6 ).
8.3.2 Super llamadas
S uper llamadas (sección 4.9.1 ) se utilizan para llamar al constructor de la clase base. Una súper llamada consiste en la
palabra clave súper seguida de una lista de argumentos encerrada entre paréntesis. Por ejemplo:
clase ColoredPoint extiende Point { constructor (x: número , y: número , color público : cadena )
{ super (x, y); } }
La primera declaración en el cuerpo de un constructor debe ser una súper llamada si se cumple lo siguiente:
En una súper llamada requerida, es un error en tiempo de compilación que las expresiones de argumento hagan
referencia a esto .
8.3.3 Constructores automáticos
Si una clase omite una declaración de constructor, se proporciona un constructor automático .
Property MemberDeclaration:
MemberVariableDeclaration
MemberFunctionDeclar ation
MemberAccessorDeclaration
Tenga en cuenta que los espacios de declaración de instancia y los miembros de propiedad estática están separados. Por
lo tanto, es posible tener miembros de instancias y propiedades estáticas con el mismo nombre.
A excepción de las anulaciones , como se describe en la sección 8.2.3 , es un error que una clase derivada declare
un miembro de propiedad con el mismo nombre y tipo (instancia o estática) que un miembro de clase base.
MemberVariableDeclaration:
AccessibilityModifier estática PropertyName TypeAnnotation inicializador ;
optar opt opt opt
El tipo asociado con una declaración de variable miembro se determina de la misma manera que una declaración de
variable ordinaria (ver sección 5.2 ).
Una declaración de variable miembro estática introduce una propiedad en el tipo de función de constructor y
opcionalmente inicializa una propiedad en el objeto de función de constructor. Los inicializadores en las declaraciones de
variables miembro estáticas se ejecutan una vez cuando se carga el script o módulo que lo contiene .
Las expresiones de inicialización para las variables miembro de instancia se evalúan en el ámbito del cuerpo del
constructor de la clase, pero no se les permite hacer referencia a parámetros o variables locales del constructor. Esta
eficacia significa que las entidades del ámbito externo s con el mismo nombre que un parámetro constructor o una
variable local son inaccesibles en las expresiones de inicializador, por ejemplo, las variables miembro.
clase Empleado { nombre público : cadena ; dirección pública : cadena ; público retirado
= falso ; gerente público : Empleado = nulo ; informes públicos : Empleado [] = []; }
es equivalente a
clase Empleado { nombre público : cadena ; dirección pública : cadena ; público retirado : booleano ; g
erente público : empleado; informes públicos : Empleado []; constructor () { this .retired
= false ; this .manager = null ; this .reports = []; } }
MemberFunctionDeclaration:
AccessibilityModifier estática PropertyName CallSignature { FunctionBody } AccessibilityModifier
optar opt optar estátic
a PropertyName CallSignature ;
opt
Una declaración de la función miembro se procesa de la misma manera como una declaración de la función ordinaria
(sección 6 ), excepto que en una función miembro esta tiene un tipo conocido .
Una declaración de función de miembro de instancia declara una propiedad en el tipo de clase y asigna un objeto de
función a una propiedad en el objeto prototipo de la clase. En el cuerpo de una declaración de función de miembro de
instancia , esta es del tipo de este (sección 3.6.3 ) de la clase .
Una declaración de función miembro estática declara una propiedad en el tipo de función de constructor y asigna un
objeto de función a una propiedad en el objeto de función de constructor. En el cuerpo de una declaración de función
miembro estática, el tipo de esta es el tipo de función constructor .
Una función miembro puede acceder a los miembros de cl as de la base anulados utilizando un acceso de súper
propiedad (sección 4.9.2 ) . Por ejemplo
clase ColoredPoint extiende Point { constructor (x: número , y: número , color público : cadena )
{ super (x, y); } public toString () { return super .toString () + " color = " + this .color;
} }
En una función miembro estática, esto representa el objeto de función constructor en el que se invocó la función
miembro estático . Por lo tanto, una llamada a ' new this () ' en realidad puede invocar un constructor de clase derivado:
clase A {
a = 1 ; static create () { return new this (); } }
la clase B se extiende A {
b = 2 ;
}
var x = A.create (); // nuevo A ()
var y = B.create (); // nuevo B ()
Tenga en cuenta que mecanografiado doesn ' t requieren o verificar que las funciones del constructor derivados son
subtipos de funciones constructoras base. En otras palabras, cambiar la declaración de ' B ' a
no provoca errores en el ejemplo, aunque la llamada al constructor de la ' crear ' la función doesn ' t especifica un
argumento (dando así el valor ' indefinido ' a ' B ' ).
MemberAccessorDeclaration:
AccessibilityModifier estática GetAccessor AccessibilityModifier
optar opt optar estática opt SetAccessor
Los accesos get y set se procesan de la misma manera que en un objeto literal (sección 4.5 ), excepto que un tipo
contextual nunca está disponible en una declaración de acceso miembro.
Una declaración de accesor de miembro de instancia declara una propiedad en el tipo de clase y define una propiedad en
el objeto prototipo de la clase con un descriptor de acceso get o set. En el cuerpo de una declaración de acceso de
miembro de instancia, esto es del tipo de este (sección 3.6.3 ) de la clase .
Una declaración de acceso miembro estático declara una propiedad en el tipo de función de constructor y define una
propiedad en el objeto de función de constructor de la clase con un acceso get o set. En el cuerpo de una declaración de
acceso de miembro estático , el tipo de este es el tipo de función de constructor .
Los accesos get y set se emiten como llamadas a ' Object.defineProperty ' en el JavaScript generado , como se describe en
la sección 8.7.1 .
8.4.4 Declaraciones de propiedad dinámica
Si el PropertyName de una declaración de miembro de propiedad es un nombre de propiedad calculado que no denota
un símbolo conocido ( 2.2.3 ), la construcción se considera una declaración de propiedad dinámica . Las siguientes
reglas se aplican a las declaraciones de propiedades dinámicas:
Una declaración de propiedad dinámica no introduce una propiedad en el tipo de clase o tipo de función de
constructor.
La expresión del nombre de propiedad de una asignación de propiedad dinámica debe ser del tipo Cualquiera o
del tipo primitivo Cadena, Número o Símbolo.
El nombre asociado con una declaración de propiedad dinámica se considera un nombre de propiedad numérico
si la expresión del nombre de la propiedad es de tipo Any o del tipo primitivo Number.
IndexMemberDeclaration:
IndexSignature ;
Una declaración de clase puede tener como máximo una declaración de miembro de índice de cadena y una declaración
de miembro de índice numérico. Todos los miembros de propiedad de instancia de una clase deben satisfacer las
restricciones implícitas por los miembros de índice de la clase como se especifica en la sección 3.9.4 .
Tenga en cuenta que rara vez tiene sentido incluir una firma de índice de cadena en una clase porque restringe todas
las propiedades de instancia de la clase. Sin embargo, las firmas de índice numérico pueden ser útiles para controlar el
tipo de elemento cuando una clase se usa de forma ordenada .
8.6 Decoradores
TODO: decoradores de documentos .
8.7 Generación de código
Cuando el objetivo de salida es ECMAScrip t 2015 o superior, los parámetros de tipo, implementa cláusulas, modificadores
de accesibilidad y declaraciones de variables miembro se eliminan en el código emitido, pero de lo contrario las
declaraciones de clase se emiten tal como están escritas. Cuando el objetivo de salida es ECMAScript 3 o 5, se realizan
reescrituras más completas, como se describe en esta sección.
8.7.1 Clase es sin cláusula extendida s
Una clase sin cláusula extiende genera JavaScript equivalente a lo siguiente:
ConstructorParam eter s es una lista separada por comas del constructor ' de parámetros na s mes .
esta . < P aram eter Nombre > = < Param eter Nombre > ;
MemberVariableAssignments es una secuencia de tareas, una para cada instancia m brasa declaración de variables con un
inicializador, en el orden en que se declaran , de la forma
esta . < M brasa Nombre > = < InitializerExpression > ;
donde Nombre de miembro es el nombre de la variable miembro e InitializerExpression es el código generado para la
expresión de inicializador.
Las declaraciones de funciones de miembros son una secuencia de declaraciones, una para cada declaración de función
de miembro o declaración de acceso de miembro , en el orden en que se declaran.
< ClassName > .prototype. < M emberName > = función ( < Func ción Param eter s > ) {
<DefaultValueAssignments>
< Func tionStatements>
}
Object.defineProperty ( < C lassName > .prototype, " < MemberName > " , {
get: function ( ) {
<GetAccessorStatements> }, set: function ( < ParameterName >) {
< Set AccessorStatements> } , enumerable: verdadero , configurable: verdadero };
y una declaración de acceso de miembro estático get o set, o un par de declaraciones de acceso de miembro estático get
o set con el mismo nombre, genera una declaración del formulario
Object.defineProperty (<ClassName>, " <MemberName> " , {
get: function () {
<GetAccessorStatements>
},
set: function (<ParameterName>) {
<SetAccessorStatements>
},
enumerable: true ,
configurable: true
};
StaticVariableAssignments es una secuencia de declaraciones, una para cada declaración de variable de miembro estático
con un inicializador, en el orden en que se declaran, del formulario
donde Member Name es el nombre de la variable estática, y InitializerExpression es el código generado para la expresión
de inicializador.
8.7.2 Clase es con cláusula extendida s
Una clase con una cláusula amplia genera JavaScript equivalente a lo siguiente:
var <NombreClase> = ( función (_super) {
__extends (<classname>, _super); de función <NombreClase> (<ConstructorParameters>) {
<DefaultValueAssignments> <SuperCallStatement> <ParameterPropertyAssignments>
<MemberVariableAssignments> <ConstructorStatements> } <MemberFunctionStatements> <
StaticVariableAssignments> return <ClassName>; }) (<BaseClassName>);
Además, los ' __extends ' función a continuación se emite en el beginnin g del archivo fuente JavaScript. Copia todas las
propiedades del objeto de función de constructor base al objeto de función de constructor derivado (para heredar
miembros estáticos ), y establece apropiadamente la propiedad ' prototipo ' del objeto de función de constructor
derivado.
BaseClassName es el nombre de clase especificado en la cláusula extend .
De lo contrario , SuperCallStatement está presente si se requiere que la función constructora comience con una súper
llamada, como se discutió en la sección 8.3.2 , y toma la forma
Un acceso de súper propiedad en el constructor, una función de miembro de instancia n o un descriptor de acceso de
miembro de instancia n genera JavaScript equivalente a
Un acceso de súper propiedad en una función miembro estática o un miembro miembro estático genera JavaScript
equivalente a
_super. <NombreDePropiedad>
donde Argumentos es el código generado para la lista de argumentos especificada en la llamada a la función.
1
9 9 Enumeraciones
Un tipo de enumeración es un subtipo distinto del tipo primitivo Número con un conjunto asociado de constantes con
nombre que definen los posibles valores del tipo de enumeración.
9.1 Declaraciones Enum
Un e num d eclaración declara un enum tipo y un objeto enum .
EnumDeclaration:
const enum BindingI dentifier { EnumBody }
opt opt
Una declaración Enum introduce un tipo con nombre (el tipo enum) y un valor con nombre (el objeto enum) en el espacio
de declaración que lo contiene. El tipo de enumeración es un subtipo distinto del tipo primitivo Número. El objeto
enum es un valor de un tipo de objeto anónimo que contiene un conjunto de propiedades, todo el tipo enum, que
corresponde a los valores declarados para el tipo enum en el cuerpo de la declaración . El objeto enum ' s tipo
furthe rmore incluye una firma índice numérico con la firma ' [x: número]: cadena ' .
El dentificador BindingI de una declaración enum puede no ser uno de los nombres de tipo predefinidos (sección 3.8.1 ).
El ejemplo
declara un subtipo del tipo primitivo Número llamado ' Color ' e introduce una variable ' Color ' con un tipo que
corresponde a la declaración
Color var : {
[x: número ]: cadena ;
Color rojo;
Color verde;
Color azul;
};
La firma del índice numérico refleja una " asignación inversa " que se genera automáticamente en cada objeto de
enumeración, como se describe en la sección 9.5 . La asignación inversa proporciona una forma conveniente de obtener la
representación de cadena de un valor enum. Por ejemplo
9.2 Miembros de Enum
El cuerpo de una declaración enum define cero o más miembros enum que son los valores nombrados del tipo
enum. Cada miembro enum tiene un valor numérico asociado del tipo primitivo introducido por la declaración enum.
EnumBody:
EnumMemberList , opt
EnumMemberList:
EnumMember
EnumMemberList , EnumMember
EnumMember:
PropertyName
PropertyName = EnumValue
EnumValue:
AssignmentExpression
Miembros de enumeración o son constantes miembros o computados miembros . Los miembros constantes tienen
valores constantes conocidos que se sustituyen en lugar de referencias a los miembros en el código JavaScript
generado . Los miembros calculados tienen valores que se calculan en tiempo de ejecución y no se conocen en tiempo de
compilación. No se realiza ninguna sustitución por referencias a miembros calculados.
Un literal numérico.
Un identificador o acceso a la propiedad que denota un miembro previamente declarado en la misma declaración
de enumeración constante.
Una expresión enum constante entre paréntesis.
Un operador unario +, - o ~ aplicado a una expresión de enumeración constante.
A +, -, *, /,%, << , >>, >>>, &, ^ o | operador aplicado a dos expresiones enum constantes.
En el ejemplo
' A ' , ' B ' , ' D ' y ' E ' son miembros constantes con valores 0, 1, 10 y 11 respectivamente, y ' C ' es un miembro calculado.
En el ejemplo
Estilo de enumeración {
Ninguno = 0 , Negrita = 1 , Cursiva = 2 , Subrayado = 4 , Énfasis = Negrita | Cursiva,
hipervínculo = negrita | Subrayado }
9.3 Declaración de fusión
Las enumeraciones son " abiertas " y las declaraciones de enumeración con el mismo nombre calificado relativo a una raíz
común (como se define en la sección 2.3 ) definen un único tipo de enumeración y contribuyen a un único objeto
enumerativo.
ISN ' t posible que una declaración de enumeración para continuar la secuencia de numeración automática de otro, y
cuando un tipo de enumeración tiene múltiples declaraciones, sólo se permite una declaración de omitir un valor para el
primer miembro.
Cuando se fusionan las declaraciones enum, todas deben especificar un modificador const o todas no especificar
ningún modificador const .
A diferencia de las declaraciones de enumeración regulares, las declaraciones de enumeración constantes se borran por
completo en el código JavaScript emitido . Por esta razón, es un error hacer referencia a un objeto de enumeración
constante en cualquier otro contexto que no sea un acceso de propiedad que selecciona uno de los miembros de la
enumeración. Por ejemplo:
Toda la declaración const enum se borra en el código JavaScript emitido . Por lo tanto, las únicas referencias permitidas al
objeto enum son aquellas que se reemplazan con un valor de miembro enum.
9.5 Codigo de GENERACION
Una declaración enum genera JavaScript equivalente a lo siguiente:
var < Nombre de enumeración > ;
( función ( <EnumName> ) {
<EnumMemberAssignments>
}) ( <EnumName> || (<EnumName> = {}) ) ;
EnumMember Assignments es una secuencia de asignaciones, una para cada miembro de la enumeración, en el orden en
que se declaran, de la forma
donde Nombre del miembro es el nombre del miembro enum y Valor es el valor constante asignado o el código
generado para la expresión del valor calculado .
Color var ;
( función (Color) {
Color [Color [ " Rojo " ] = 0 ] = " Rojo " ;
Color [Color [ " Verde " ] = 1 ] = " Verde " ;
Color [Color [ " Azul " ] = 2 ] = " Azul " ;
}) (Color || (Color = {} ) );
1
10 Espacio de nombres m
Los espacios de nombres proporcionan un mecanismo para organizar el código y las declaraciones en jerarquías de
contenedores con nombre. Los espacios de nombres tienen miembros nombrados que cada uno denota un valor, un tipo
o un espacio de nombres, o alguna combinación de los mismos , y esos miembros pueden ser locales o exportados . El
cuerpo de un espacio de nombres corresponde a una función que se ejecuta una vez, proporcionando así un mecanismo
para mantener el estado local con un aislamiento asegurado. Los espacios de nombres pueden considerarse como una
formalización del patrón de expresión de función invocada inmediatamente (IIFE).
NamespaceDeclaration :
namespace IdentifierPath { NamespaceBody }
IdentifierPath:
Binding Identifier
IdentifierPath . BindingI dentificador
Los espacios de nombres se declaran usando la palabra clave de espacio de nombres , pero para la compatibilidad con
versiones anteriores de TypeScript , también se puede usar una palabra clave de módulo .
Los espacios de nombres son instanciados o no instanciados . Un espacio de nombres no instanciado es un espacio de
nombres que contiene solo tipos de interfaz , alias de tipo y otro espacio de nombres no instanciado . Un
instanciado espacio de nombres es un espacio de nombres que doesn ' t cumplir con esta definición . En términos
intuitivos, un n instanciada espacio de nombres es uno para el que un espacio de nombres de ejemplo se crea , mientras
que un no instanciado- espacio de nombres es uno para el que no se genera ningún código.
Por encima , cuando ' M ' se utiliza como una PrimaryExpression denota una instancia de objeto con un único miembro
de ' un ' y cuando ' M ' se utiliza como una NameSpaceName denota un recipiente con un único miembro de tipo ' P ' . La
línea final en el ejemplo es un error porque ' m ' es una variable a la que no se puede hacer referencia en un nombre de
tipo.
Una declaración de espacio de nombres que especifica un IdentifierPath con más de un identificador es equivalente a una
serie de declaraciones de espacio de nombres de identificador único necesarias donde todos menos el más externo se
exportan automáticamente. Por ejemplo:
corresponde a
La jerarquía formada por el espacio de nombres y los nombres de tipo con nombre refleja parcialmente la formada por
instancias y miembros de espacio de nombres. El ejemplo
las dos ocurrencias de 'ABC' de hecho se refieren a diferentes entidades. Es el contexto de las ocurrencias lo que
determina si 'ABC' se procesa como un nombre de tipo o una expresión.
NamespaceBody :
NamespaceElement s opt
NamespaceElement s:
NamespaceElement
NamespaceElement s NamespaceElement
NamespaceElement :
Declaración
LexicalDeclaration
FunctionDeclaration
GeneratorDeclaration
ClassDeclaration
InterfaceDeclaration
TypeAliasDeclaration
EnumDeclaration
NamespaceDeclaration
AmbientDeclaration
Import Alias Declaración
Exportar NamespaceElement
Exportar NamespaceElement :
export VariableStatement export LexicalDeclaration export FunctionDeclaration export GeneratorDeclaration ex
port ClassDeclaration export InterfaceDeclaration export TypeAliasDeclaration export EnumDeclaration export
NamespaceDeclaration export AmbientDeclaration export ImportA lias Declaración
Un EntityName que consiste en un único identificador se resuelve como un Nombre de espacio de nombres y, por lo tanto,
se requiere que haga referencia a un espacio de nombres . El alias local resultante hace referencia al espacio de nombres
dado y se clasifica como un espacio de nombres .
Un EntityName que consta de más de un identificador se resuelve como un Nombre de espacio de nombres seguido de un
identificador que nombra una entidad exportada en el espacio de nombres dado . El alias local resultante tiene todos los
significados de la entidad referenciada . (Hasta tres significados distintos son posibles para un nombre de entidad: valor ,
tipo y espacio de nombres ). En efecto, es como si la entidad importada se declarara localmente con el nombre de alias
local.
En el ejemplo
' Y ' es un alias local para el espacio de nombres no instanciado ' A ' . Si la declaración de ' A ' se cambia de manera
que ' A ' se convierte en un espacio de nombres instanciado , por ejemplo, al incluir una declaración de variable en ' A ' , la
declaración de importación en ' B ' anterior sería un error porque la expresión ' A ' no ' t hacen referencia al espacio de
nombres ejemplo de espacio de nombres ' A ' .
Cuando una declaración de importación incluye un modificador de exportación , se exportan todos los significados del
alias local.
10,4 Declaraciones de exportación
Una declaración de exportación declara un miembro de espacio de nombres accesible externamente . Una declaración de
exportación es simplemente una declaración regular prefijada con la palabra clave exportar .
Los miembros del espacio de declaración de exportación de un espacio de nombres (sección 2.3 ) constituyen el conjunto
de miembros de exportación del espacio de nombres . El tipo de instancia de un espacio de nombres es un tipo de
objeto con una propiedad para cada miembro en el conjunto de miembros de exportación del espacio de nombres que
denota un valor.
Un miembro exportado depende de un conjunto (posiblemente vacío) de tipos con nombre (sección 3.7 ). Esos tipos
nombrados deben ser al menos tan accesibles como el miembro exportado , o de lo contrario se produce un error.
Los tipos nombrados de los que depende un miembro son los tipos nombrados que ocurren en el cierre transitivo de la
relación directamente depende de la definida de la siguiente manera:
Se dice que un tipo T con nombre que tiene un espacio de nombres raíz R (sección 2.3 ) es al menos tan accesible
como un miembro M si
En el ejemplo
interfaz A {x: cadena ; }
espacio de nombres M { interfaz de exportación B {x: A; } interfaz de exportación C {x: B; } función
de exportación foo (c: C) {…} }
10,5 Declaración de fusión
Los espacios de nombres son " abiertos " y las declaraciones de espacios de nombres con el mismo nombre calificado
relativo a una raíz común (como se define en la sección 2.3 ) contribuyen a un único espacio de nombres . Por ejemplo, las
siguientes dos declaraciones de un espacio de nombres ' externo ' podrían ubicarse en archivos de origen separados.
Archivo a.ts:
Archivo b.ts:
Suponiendo que los dos archivos fuente son parte del mismo programa, las dos declaraciones tendrán el espacio de
nombres global como su raíz común y, por lo tanto, contribuirán a la misma instancia de espacio de nombres , cuyo tipo
de instancia será:
{
a: número ;
b: número ;
interno: {
x: número ;
y: número ;
};
}
Al fusionar una función y un espacio de nombres , el tipo del objeto de función se fusiona con el tipo de instancia
del espacio de nombres . En efecto, las sobrecargas o la implementación de la función proporcionan las firmas de
llamada y los miembros exportados del espacio de nombres proporcionan las propiedades del tipo combinado.
Al fusionar una clase y un espacio de nombres , el tipo del objeto de función constructor se combina con el tipo
de instancia del espacio de nombres . En efecto, las sobrecargas o la implementación del constructor de la
clase proporcionan las firmas de construcción , y los miembros estáticos de la clase y los miembros exportados
del espacio de nombres proporcionan las propiedades del tipo combinado. Es un error tener miembros de clase
estáticos y miembros de espacio de nombres exportados con el mismo nombre.
Al fusionar una enumeración y un espacio de nombres , el tipo del objeto de enumeración se fusiona con el tipo
de instancia del espacio de nombres . En efecto, los miembros de la enumeración y los miembros exportados
del espacio de nombres proporcionan las propiedades del tipo combinado. Es un error tener miembros de
enumeración y miembros de espacio de nombres exportados con el mismo nombre.
Al fusionar una función no ambiental o una declaración de clase y una declaración de espacio de nombres no ambiental ,
la declaración de función o clase debe ubicarse antes de la declaración de espacio de nombres en el mismo archivo
fuente. Esto garantiza que la instancia de objeto compartido se cree como un objeto de función. (Si bien es posible
agregar propiedades a un objeto después de su creación, no es posible hacer que un objeto sea " invocable " después del
hecho).
El ejemplo
Punto de interfaz {
x: número ;
y: número ;
}
punto de función (x: número , y: número ) : Punto { return {x: x, y: y}; }
10.6 Generación de código
Un espacio de nombres genera código JavaScript que es equivalente al siguiente:
var <Alias> = <EntityName>;
Este código se emite solo si se hace referencia a la entidad importada como PrimaryExpression en algún lugar del cuerpo
del espacio de nombres de importación . Si se hace referencia a una entidad importada solo
como TypeName o NamespaceName , no se emite nada. Esto garantiza que los tipos declarados en un espacio de
nombres puedan ser referenciados a través de un alias de impo rt en otro espacio de nombres sin sobrecarga de tiempo
de ejecución .
Cuando se exporta una variable, todas las referencias a la variable en el cuerpo del espacio de nombres se reemplazan con
Cuando se exporta una función, clase, enumeración o espacio de nombres , al código generado para la entidad le sigue
una declaración de asignación del formulario
1
11 S cripts y módulos
SourceFile:
ImplementationSourceFile
DeclarationSourceFile
ImplementationSourceFile:
ImplementationScript
ImplementationModule
DeclarationSourceFile:
DeclarationScript
DeclarationModule
Los archivos fuente con la extensión '.ts' son archivos fuente de implementación que contienen declaraciones y
declaraciones, y los archivos fuente con la extensión '.d.ts' son archivos fuente de declaración que contienen
declaraciones .
Los archivos fuente de declaración son un subconjunto estricto de archivos fuente de implementación y se utilizan para
declarar la información de tipo estático asociada con el código JavaScript existente de manera adjunta. Son
completamente opcionales, pero permiten que el compilador TypeScript y las herramientas proporcionen una mejor
verificación y asistencia al integrar el código JavaScript existente y las bibliotecas en una aplicación TypeScript.
Cuando un texto mecanografiado se compila el programa, todos los del programa ' s archivos de origen se procesan
juntos . Las declaraciones y declaraciones en diferentes archivos fuente pueden depender unas de otras, posiblemente de
manera circular. De manera predeterminada, se genera un archivo de salida de JavaScript para cada archivo fuente de
implementación en una compilación, pero no se genera salida de los archivos fuente de declaración.
Un comentario de la forma /// <reference path = " … " /> que ocurre antes del primer token en un archivo
fuente agrega una dependencia en el archivo fuente especificado en el argumento de ruta. La ruta se resuelve en
relación con el directorio del archivo fuente que lo contiene .
Una declaración de importación de módulo que especifica un nombre de
módulo relativo (sección 11.3.1 ) resuelve el nombre relativo al directorio del archivo
fuente que lo contiene . Si existe un archivo fuente con la ruta resultante y la extensión de archivo ' .ts ' , ese archivo
se agrega como una dependencia. De lo contrario, si existe un archivo fuente con la ruta resultante y la extensión de
archivo ' .d.ts ' , ese archivo se agrega como una dependencia.
Una declaración de importación de módulo que especifica un nombre de módulo de nivel
superior (sección 11.3.1 ) resuelve el nombre de una manera dependiente del host ( generalmente resolviendo el
nombre relativo a una raíz de espacio de nombre de módulo o buscando el nombre en una serie de directorios) . Si
un archivo fuente con extensión ' ts ' o ' .d.ts ' correspondientes a la referencia se encuentra , ese archivo se añade
como una dependencia.
A su vez, los archivos incluidos como dependencias tienen sus referencias analizadas de manera transitiva hasta que se
hayan determinado todas las dependencias.
11.2 Guiones
Los archivos de origen que no contienen declaraciones de importación o exportación de módulos se clasifican
como scripts . Las secuencias de comandos forman el espacio de nombres global único y las entidades declaradas en
las secuencias de comandos tienen alcance en todas partes en un programa.
ImplementationScript:
ImplementationScriptElements opt
ImplementationScriptElements:
ImplementationScriptElement
ImplementationScriptElements ImplementationScriptElement
ImplementationScriptElement:
ImplementationElement
AmbientModuleDeclaration
ImplementationElement:
Statement
LexicalDeclaration
FunctionDeclaration
GeneratorDeclaration
ClassDeclaration
InterfaceDeclaration
TypeAliasDeclaration
EnumDeclaration
Namespace Declaración
AmbientDeclaration
ImportAlias Declaración
DeclarationScript:
DeclarationScriptElements opt
DeclarationScriptElements:
DeclarationScriptElement
DeclarationScriptElements DeclarationScriptElement
DeclarationScriptElement:
DeclarationElement
AmbientModuleDeclaration
DeclarationElement:
InterfaceDeclaration
TypeAliasDeclaration
Namespace Declaración
AmbientDeclaration
ImportAlias Declaración
El orden de inicialización de los scripts que componen el espacio de nombres global depende en última instancia del
orden en que se cargan los archivos JavaScript generados en tiempo de ejecución (que, por ejemplo, pueden controlarse
mediante etiquetas <script /> que hacen referencia al JavaScript generado archivos).
11,3 Módulos
Los archivos de origen que contienen al menos una declaración de importación o exportación de módulo se
consideran módulos separados . Las entidades no exportadas declaradas en un módulo solo están dentro del alcance de
ese módulo , pero las entidades exportadas pueden importarse a otros módulos mediante declaraciones de importación.
ImplementationModule:
ImplementationModuleElements opt
ImplementationModuleElements:
ImplementationModuleElement
ImplementationModuleElements ImplementationModuleElement
ImplementationModuleElement:
ImplementationElement
ImportDeclaration
ImportAlias Declaración
ImportRequireDeclaration
ExportImplementationElement
ExportDefaultImplementationElement
Export List Declaración
Exportación Asignación
DeclarationModule:
DeclarationModuleElements opt
DeclaraciónMóduloElementos:
DeclaraciónMóduloElemento
DeclaraciónMóduloElementos DeclaraciónMóduloElemento
DeclarationModuleElement:
DeclaraciónElemento
ImportaciónDeclaración
ImportaciónAlias Declaración
ExportaciónDeclaraciónElemento
Exportación predeterminada DeclaraciónElemento
Exportar lista Declaración
Exportar asignación
El orden de inicialización de los módulos está determinado por el cargador de módulos que se utiliza y no está
especificado por el lenguaje TypeScript. Sin embargo, por lo general, los módulos que no dependen circularmente se
cargan e inicializan automáticamente en el orden correcto.
El patrón de generación de código de módulo deseado se selecciona a través de una opción de compilador y no afecta
el código fuente de TypeScript . De hecho, es posible crear módulos que se puedan compilar para usarlos tanto en
el lado del servidor ( por ejemplo, usando node.js ) como en el lado del cliente (usando un cargador compatible con
AMD ) sin cambios en el código fuente de TypeScript .
11.3.1 Nombres de módulos
Los módulos son identificados y referenciados usando los nombres de los módulos. La siguiente definición se alinea con la
proporcionada en º e CommonJS Módulos 1.0 especificación .
11.3.2 Declaraciones de Importación
Las declaraciones de importación se utilizan para importar entidades de otros módulos y proporcionar enlaces para ellas
en el módulo actual.
importar * como m de "mod" ;
importa el módulo con el nombre dado y crea un enlace local para el módulo en sí . El enlace local se clasifica como un
valor (que representa la instancia del módulo) y un espacio de nombres (que representa un contenedor de tipos y
espacios de nombres).
importar {x, y, z} desde "mod" ;
importa un módulo determinado y crea enlaces locales para una lista específica de miembros exportados del
módulo . Los nombres especificados deben hacer referencia a una entidad en el conjunto de miembros de
exportación ( 11.3.4.4 ) del módulo dado. Los enlaces locales tienen el mismo nombre s y clasificación s como las
entidades que representan a menos que las cláusulas se utilizan para que especifican diferentes nombres locales:
importar d desde "mod" ;
importar {predeterminado como d} desde "mod" ;
importar "mod" ;
importa el módulo dado sin crear enlaces locales (esto es útil solo si el módulo importado tiene efectos secundarios).
11.3.3 Importar requiere declaraciones
Me Mport requiero declarati complementos existen para mantener la compatibilidad con versiones anteriores de
mecanografiado.
importar m = requerir ( "mod" );
importar * como m de "mod" ;
siempre que el módulo al que se hace referencia no contenga ninguna asignación de exportación .
11.3.4 Declaraciones de exportación
Una declaración de exportación declara uno o más miembros del módulo exportados. Los miembros exportados de un
módulo pueden importarse en otros módulos mediante declaraciones de importación ( 11.3.2 ).
11.3.4.1 Modificadores de exportación
En el cuerpo de un módulo, una declaración puede exportar la entidad declarada al incluir un modificador
de exportación .
ExportImplementationElement:
export VariableStatement export LexicalDeclaration export FunctionDeclaration export GeneratorDeclaration ex
port ClassDeclaration export InterfaceDeclaration export TypeAliasDeclaration export EnumDeclaration export
NamespaceDeclaration export AmbientDeclaration export ImportAlias Declaración
ExportDeclarationElement:
export InterfaceDeclaration export TypeAliasDeclaration export AmbientDeclaration export ImportAlias Declara
ción
Además de introducir un nombre en el espacio de declaración local del módulo, una declaración exportada introduce el
mismo nombre con la misma clasificación en el espacio de declaración de exportación del módulo. Por ejemplo, la
declaración
introduce un punto de nombre local y un punto de nombre exportado que hacen referencia a la función.
ExportDefaultImplementationElement:
export default FunctionDeclaration export default GeneratorDeclaration export default ClassDeclaration exp
ort default AssignmentExpression ;
ExportDefaultDeclarationElement:
exportación predeterminada AmbientF unctionDeclaration exportación predeterminada AmbientC lassDeclarati
on export default IdentifierReference ;
punto predeterminado de exportación ;
exportar {punto por defecto};
Punto de interfaz {
x: número ;
y: número ;
}
Punto de función (x: número , y: número ): Punto { return {x, y}; }
punto predeterminado de exportación ;
Un ExportDefault ImplementationElement para cualquier expresión que no sea un identificador único introduce un
valor denominado default en el espacio de declaración de exportación del módulo contenedor. Por ejemplo, la
declaración
exportar por defecto "hola" ;
Una n ExportListDeclaration sin FromClause exporta entidades del módulo actual. En una declaración de la forma
exportar {x };
t él nombre de x debe hacer referencia a una entidad declarada en el módulo actual o en el espacio de nombres global, y
la declaración introduce una entidad con el mismo nombre y significar ing en el espacio declaración de exportación del
módulo que contiene.
Una n ExportListDeclaration con una FromClause reexporta entidades desde un módulo específico. En una declaración de
la forma
exportar {x} desde "mod" ;
introduce entidades nombradas x , b , y c en el espacio declaración de exportación del módulo que contiene con el
mismo significado que las entidades locales nombrados x , y , y z , respectivamente.
Una declaración ExportListDeclaration que especifica * en lugar de una ExportClause se denomina declaración estrella de
exportación . Una declaración estrella de exportación reexporta todos los miembros de un módulo específico.
exportar * desde "mod" ;
Los miembros exportados explícitamente tienen prioridad sobre los miembros reexportados utilizando declaraciones de
estrellas de exportación, como se describe en la siguiente sección.
Añadir M a P .
Añadir a E de cada miembro en el espacio de declaración de exportación de M con un nombre que no está ya
en E .
Para cada declaración de exportación estrellas en M , en el orden de declaración, procesar el módulo de referencia
si no está ya en P .
El tipo de instancia de un módulo es un tipo de objeto con una propiedad para cada miembro en el conjunto de
miembros de exportación del módulo que denota un valor.
Si un módulo contiene una asignación de exportación , es un error que el módulo también contenga declaraciones de
exportación. Los dos tipos de exportaciones son mutuamente excluyentes.
11.3.5 Asignaciones de exportación
Existen asignaciones de exportación para compatibilidad con versiones anteriores de TypeScript. Una asignación de
exportación designa a un miembro del módulo como la entidad que se exportará en lugar del propio módulo .
ExportAssignment:
export = Identificador de referencia ;
Un módulo que contiene una asignación de exportación se puede importar utilizando una importación requiere
declaración ( 11.3.3 ), y el alias local en troduced por la importación requiere declaración a
continuación, adquiere todo significado s del identificador de llamada en la asignación de exportación.
Un módulo que contiene una asignación de exportación también se puede importar utilizando una declaración de
importación regular ( 11.3.2 ) siempre que la entidad a la que se hace referencia en la asignación de exportación se
declare como un espacio de nombres o como una variable con una anotación de tipo.
export = Point;
clase Point { constructor ( public x: número , public y: número ) {} origen estático = nuevo punto
( 0 , 0 ); }
Cuando se importa ' point.ts ' en otro módulo, el alias de importación hace referencia a la clase exportada y se puede usar
como un tipo y como una función de constructor:
import Pt = require ( " ./ point " );
var p1 = nuevo Pt ( 10 , 20 ); var p2 = Pt.origin;
Tenga en cuenta que no es necesario que el alias de importación use el mismo nombre que la entidad exportada.
11.3.6 Módulos CommonJS
La definición de Módulos CommonJS especifica una metodología para escribir módulos JavaScript con privacidad
implícita, la capacidad de importar otros módulos y la capacidad de exportar miembros explícitamente. Un sistema
compatible con Common JS proporciona una función ' require ' que se puede usar para cargar de forma sincrónica
otros módulos para obtener su instancia de módulo único a n, así como una variable ' exportar ' a la que un módulo
puede agregar propiedades para definir su API externa.
Archivo main.js :
Archivo log.js:
Una declaración de importación de módulo se representa en el JavaScript generado como una variable inicializada por
una llamada a la función ' requerir ' proporcionada por el sistema de módulo ho st. Se emite una declaración de variable
y una llamada ' requerida ' para un módulo importado particular solo si el módulo importado , o un alias local
(sección 10.3 ) que hace referencia al módulo importado, se hace referencia como una Expresión primaria en algún lugar
del cuerpo del módulo de importación. Si se hace referencia a un módulo importado solo
como NamespaceName o TypeQueryExpression , no se emite nada.
Un ejemplo:
Archivo geometry.ts :
Archivo game.ts :
Si el módulo ' juego ' hubiera sido escrito solo para hacer referencia a ' geometría ' en una posición de tipo
importar * como g desde "./geometry" ; sea p: g.Point = {x: 10 , y: 20 };
11.3.7 Módulos AMD
La especificación de definición de módulo asíncrono (AMD ) amplía la especificación de módulos CommonJS con un
patrón para crear módulos cargables asincrónicamente con dependencias asociadas . Usando el patrón AMD ,
los módulos se emiten como llamadas a una función global ' definir ' que toma una matriz de dependencias, especificadas
como nombres de módulos, y una función de devolución de llamada que contiene el cuerpo del
módulo. El mundial ' definir ' la función i s proporcionada por incluyendo un cargador compatible con AMD en
la aplicación . El cargador arregla para cargar de forma asíncrona los módulos ' s dependencias y, al finalizar, llama a la
función de devolución de llamada que pasa resueltos módulo casos como argumentos en el orden en que se enumeran
en la matriz de dependencia.
Archivo main.js:
Archivo log.js:
1
12 ambientes
Las declaraciones ambientales se utilizan para proporcionar escritura estática sobre el código JavaScript existente. Las
declaraciones ambientales difieren de las declaraciones regulares en que no se emite ningún código JavaScript para
ellas. En lugar de introducir nuevas variables, funciones, clases, enumeraciones o espacios de nombres , las declaraciones
ambientales proporcionan información de tipo para entidades que existen " ambientalmente " y se incluyen en un
programa por medios externos, por ejemplo, haciendo referencia a una biblioteca JavaScript en un <script / > etiqueta.
12,1 Declaraciones ambientales
Las declaraciones ambientales se escriben usando la palabra clave declare y pueden declarar variables, funciones, clases,
enumeraciones, espacios de nombres o módulos.
AmbientDeclaration:
declare AmbientVariableDeclaration declare AmbientFunctionDeclaration declare AmbientClassDeclaration dec
lare AmbientEnumDeclaration declare Ambient NamespaceDeclaration
AmbientVariableDeclaration:
var AmbientBindingList ; deja AmbientBindingList ; const AmbientBindingList ;
AmbientBindingList:
AmbientBinding
AmbientBindingList , AmbientBinding
AmbientBinding:
BindingIdentifier TypeAnnotation opt
Una declaración de variable ambiental puede incluir opcionalmente una anotación de tipo. Si no hay ninguna anotación
de tipo, se supone que la variable tiene el tipo Any.
Una declaración de variable ambiental no permite que esté presente una expresión inicializadora.
AmbientFunctionDeclaration:
function BindingI dentifier CallSignature ;
Las funciones ambientales se pueden sobrecargar especificando múltiples declaraciones de funciones ambientales con el
mismo nombre, pero es un error declarar múltiples sobrecargas que se consideran idénticas (sección 3.11.2 ) o que solo
difieren en sus tipos de retorno.
Las declaraciones de funciones ambientales no pueden especificar los cuerpos de una función y no permiten valores de
parámetros predeterminados.
AmbientClassDeclaration:
class BindingI dentifier TypeParameters ClassHeritage { AmbientClassBody }
opt
AmbientClassBody:
AmbientClassBodyElements opt
AmbientClassBodyElements:
AmbientClassBodyElement
AmbientClassBodyElements AmbientClassBodyElement
AmbientClassBodyElement:
AmbientConstructorDeclaration
Ambient Property MemberDeclaration
IndexSignature
AmbientConstructorDeclaration:
constructor ( ParameterList ) ;
opt
12.1.4 Declaraciones de enumeración ambiental
Una n enumeración ambiental es gramaticalmente equivalente a una declaración de enumeración no ambiental.
AmbientEnumDeclaration:
EnumDeclaration
Las declaraciones de enumeración ambiental difieren de las declaraciones de enumeración no ambiental de dos maneras:
En la declaración de enumeración ambiental s , todos los valores especificados en las declaraciones de miembros
de enumeración se deben clasificar como expresiones de enumeración constantes.
En las declaraciones de enumeración ambiental que no especifican ningún modificador constante , las
declaraciones de miembros de enumeración que omiten un valor se consideran miembros calculados (en lugar de
tener asignados valores de incremento automático).
Las declaraciones de enumeración ambiental se procesan de la misma manera que las declaraciones de enumeración no
ambientales.
Ambient NamespaceDeclaration :
nombre de espacio IdentifierPath { Ambient NamespaceBody }
Ambient NamespaceBody :
Ambient NamespaceElement s opt
mportAlias Declaración
12,2 Declaraciones de módulo ambiental
Una declaración de módulo de ambiente declara un módulo. Este tipo de declaración se permite solo en el nivel superior
en un archivo fuente que contribuye al espacio de nombres global (sección 11.1 ) . El StringLiteral mu st especificar un
nivel superior nombre del módulo. No se permiten nombres de módulos relativos .
AmbientModuleDeclaration :
declare module StringLiteral { DeclarationModule }
Si un ambiente declaración módulo incluye una asignación de exportación, es un error para cualquiera de las
declaraciones con en el módulo para especificar una exportación m odifier. Si una declaración de módulo ambiental no
contiene asignación de exportación, las entidades declaradas en el módulo se exportan independientemente de si sus
declaraciones incluyen el modificador de exportación opcional .
declare module " io " { export function readFile (filename: string ): string ; }
declare module " io " { export function readFile (filename: string ): string ; función
de exportación writeFile (nombre de archivo: cadena , datos: cadena ): vacío ; }
1
Una gramática
Apéndice O producciones ólo que son nuevas o modificada a partir de la Gramática ECMAScript.
A.1 Tipos
TypeParameters:
< TypeParameterList >
TypeParameterList:
TypeParameter
TypeParameterList , TypeParameter
Tipo Parámetro:
BindingIdentifier Restricción
opt
Restricción:
extiende el tipo
TypeArguments:
< TypeArgumentList >
TypeArgumentList:
TypeArgument
TypeArgumentList , TypeArgument
Tipo Argumento:
Tipo
Tipo:
UnionOrIntersectionOrPrimaryType
FunctionType
ConstructorType
UnionOrIntersectionOrPrimaryType:
UnionType
IntersectionOrPrimaryType
IntersectionOrPrimaryType:
IntersectionType
PrimaryType
Tipo primario :
ParenthesizedType
PredefinedType
TypeReference
ObjectType
ArrayType
TupleType
TypeQuery
ThisType
ParenthesizedType:
( Tipo )
PredefinedType:
cualquier
número
boolean
string
symbol
void
TypeReference:
TypeName [no LineTerminator aquí] TypeArguments
opt
TypeName:
IdentifierReference
NamespaceName . IdentificadorReferencia
NamespaceName:
IdentifierReference
NamespaceName . IdentificadorReferencia
ObjectType:
{ TypeBody }
opt
TypeBody:
TypeMemberList ; TypeMemberList ,
opt opt
TypeMemberList:
TypeMember
TypeMemberList ; TypeMember TypeMemberList , TypeMember
TypeMember:
PropertySignature
CallSignature
ConstructSignature
IndexSignature
MethodSignature
ArrayType:
PrimaryType [no LineTerminator aquí] [ ]
TupleType:
[ TupleElementTypes ]
TupleElementTypes:
TupleElementType
TupleElementTypes , TupleElementType
TupleElementType:
Type
UnionType:
UnionOrIntersectionOrPrimaryType | IntersectionOrPrimaryType
IntersectionType:
IntersectionOrPrimaryType & PrimaryType
FunctionType:
TypeParameters ( ParameterList ) => Tipo
opt opt
ConstructorType:
new TypeParameters ( ParameterList ) => Tipo
opt opt
TypeQuery:
typeof TypeQueryExpression
TypeQueryExpression:
IdentifierReference
TypeQueryExpression . IdentifierName
ThisType:
this
PropertySignature:
PropertyName ? Tipo Anotación
opt opt
PropertyName:
IdentifierName
StringLiteral
NumericLiteral
TypeAnnotation
:: Type
CallSignature:
TypeParameters ( ParameterList ) TypeAnnotation
opt opt opt
ParameterList:
RequiredParameterList
OpcionalParameterList
RestParameter
RequiredParameterList , OpcionalParameterList RequiredParameterList , RestParameter OpcionalParameterList ,
RestParameter RequiredParameterList , OpcionalParameterList , RestParameter
RequiredParameterList:
RequiredParameter
RequiredParameterList , RequiredParameter
RequiredParameter:
AccessibilityModifier BindingIdentifierOrPattern TypeAnnotation BindingIdentifier : StringLiteral
opt opt
AccessibilityModifier:
público
privado
protegido
BindingIdentifierOrPattern:
BindingIdentifier
BindingPattern
OpcionalParameterList:
OpcionalParameter
OpcionalParameterList , OpcionalParameter
OpcionalParameter:
AccessibilityModifier BindingIdentifierOrPattern ? TypeAnnotation AccessibilityModifier BindingIdentifierOrPat
opt opt opt
RestParameter:
... BindingIdentifier TypeAnnotation
opt
ConstructSignature:
nuevo TypeParameters ( ParameterList ) TypeAnnotation
opt opt opt
IndexSignature:
[ BindingIdentifier : string ] TypeAnnotation [ BindingIdentifier : número ] TypeAnnotation
MethodSignature:
PropertyName ? CallSignature
opt
TypeAliasDeclaration:
type BindingIdentifier TypeParameters = Type ;
opt
A.2 Expresiones
PropertyDefinition: (Modificado) IdentifierReference CoverInitializedName PropertyName : AssignmentExpression Prop
ertyName CallSignature { FunctionBody } GetAccessor SetAccessor
GetAccessor:
get PropertyName ( ) TypeAnnotation { FunctionBody }
opt
SetAccessor:
set PropertyName ( BindingIdentifierOrPattern TypeAnnotation ) { FunctionBody }
opt
UnaryExpression: (Modificado) ... < Tipo > UnaryExpression
A.3 Declaraciones
Declaración: (Modificado) ... Tipo de declaración de interfaz Declaración de alias Declaración de enumeración
SimpleVariableDeclaration:
BindingIdentifier TypeAnnotation Initializer
opt opt
DestructuringVariableDeclaration:
BindingPattern TypeAnnotation Initializer
opt
SimpleLexicalBinding:
BindingIdentifier TypeAnnotation Initializer
opt opt
DestructuringLexicalBinding:
BindingPattern TypeAnnotation Initializer
opt opt
A.4 Funciones
FunctionDeclaration: (modificada) función BindingIdentifier CallSignature { FunctionBody } función BindingIdentifi
opt
A.5 Interfaces
InterfaceDeclaration:
interfaz BindingIdentifier TypeParameters InterfaceExtendsClause ObjectType
opt opt
InterfaceExtendsClause:
extiende ClassOrInterfaceTypeList
ClassOrInterfaceTypeList:
ClassOrInterfaceType
ClassOrInterfaceTypeList , ClassOrInterfaceType
ClassOrInterfaceType:
TypeReference
A.6 Clases
ClassDeclaration: clase (modificada) BindingIdentifier TypeParameters ClassHeritage { ClassBody }
opt opt
ClassHeritage: (Modificado) ClassExtendsClause ImplementsClause
opt opt
ClassExtendsClause:
extiende ClassType
ClassType:
TypeReference
ImplementsClause:
implementa ClassOrInterfaceTypeList
ConstructorDeclaration:
AccessibilityModifier constructor ( ParameterList ) { FunctionBody } AccessibilityModifier constructor (
opt opt opt
ParameterList ) ;
opt
PropertyMemberDeclaration:
MemberVariableDeclaration
MemberFunctionDeclaration
MemberAccessorDeclaration
MemberVariableDeclaration:
AccessibilityModifier estática PropertyName TypeAnnotation inicializador ;
optar opt opt opt
MemberFunctionDeclaration:
AccessibilityModifier estática PropertyName CallSignature { FunctionBody } AccessibilityModifier
optar opt optar estátic
a PropertyName CallSignature ;
opt
MemberAccessorDeclaration:
AccessibilityModifier estática GetAccessor AccessibilityModifier
optar opt optar estática opt SetAccessor
IndexMemberDeclaration:
IndexSignature ;
A.7 Enums
EnumDeclaration:
const enum BindingIdentifier { EnumBody }
opt opt
EnumBody:
EnumMemberList , opt
EnumMemberList:
EnumMember
EnumMemberList , EnumMember
EnumMember:
PropertyName
PropertyName = EnumValue
EnumValue:
AssignmentExpression
A.8 Espacios de nombres
NamespaceDeclaration:
namespace IdentifierPath { NamespaceBody }
IdentifierPath:
BindingIdentifier
IdentifierPath . BindingIdentifier
NamespaceBody:
NamespaceElements opt
NamespaceElements:
NamespaceElement
NamespaceElements NamespaceElement
NamespaceElement:
Declaración
LexicalDeclaration
FunctionDeclaration
GeneratorDeclaration
ClassDeclaration
InterfaceDeclaration
TypeAliasDeclaration
EnumDeclaration
NamespaceDeclaration
AmbientDeclaration
ImportAliasDeclaration
ExportNamespaceElement
ExportNamespaceElement:
export VariableStatement export LexicalDeclaration export FunctionDeclaration export GeneratorDeclaration ex
port ClassDeclaration export InterfaceDeclaration export TypeAliasDeclaration export EnumDeclaration export
NamespaceDeclaration export AmbientDeclaration export ImportAliasDeclaration
ImportAliasDeclaration:
import BindingIdentifier = EntityName ;
EntityName:
NamespaceName
NamespaceName . IdentificadorReferencia
A.9 Scripts y módulos
SourceFile:
ImplementationSourceFile
DeclarationSourceFile
ImplementationSourceFile:
ImplementationScript
ImplementationModule
DeclarationSourceFile:
DeclarationScript
DeclarationModule
ImplementationScript:
ImplementationScriptElements opt
ImplementationScriptElements:
ImplementationScriptElement
ImplementationScriptElements ImplementationScriptElement
ImplementationScriptElement:
ImplementationElement
AmbientModuleDeclaration
ImplementationElement:
Statement
LexicalDeclaration
FunctionDeclaration
GeneratorDeclaration
ClassDeclaration
InterfaceDeclaration
TypeAliasDeclaration
EnumDeclaration
NamespaceDeclaration
AmbientDeclaration
ImportAliasDeclaration
DeclarationScript:
DeclarationScriptElements opt
DeclarationScriptElements:
DeclarationScriptElement
DeclarationScriptElements DeclarationScriptElement
DeclarationScriptElement:
DeclarationElement
AmbientModuleDeclaration
DeclarationElement:
InterfaceDeclaration
TypeAliasDeclaration
NamespaceDeclaration
AmbientDeclaration
ImportAliasDeclaration
ImplementationModule:
ImplementationModuleElements opt
ImplementationModuleElements:
ImplementationModuleElement
ImplementationModuleElements ImplementationModuleElement
ImplementationModuleElement:
ImplementationElement
ImportDeclaration
ImportAliasDeclaration
ImportRequireDeclaration
ExportImplementationElement
ExportDefaultImplementationElement
ExportListDeclaration
ExportAssignment
DeclarationModule:
DeclarationModuleElements opt
DeclaraciónMóduloElementos:
DeclaraciónMóduloElemento
DeclaraciónMóduloElementos DeclaraciónMóduloElemento
DeclarationModuleElement:
DeclarationElement
ImportDeclaration
ImportAliasDeclaration
ExportDeclarationElement
ExportDefaultDeclarationElement
ExportListDeclaration
ExportAssignment
ImportRequireDeclaration:
import BindingIdentifier = require ( StringLiteral ) ;
ExportImplementationElement:
export VariableStatement export LexicalDeclaration export FunctionDeclaration export GeneratorDeclaration ex
port ClassDeclaration export InterfaceDeclaration export TypeAliasDeclaration export EnumDeclaration export
NamespaceDeclaration export AmbientDeclaration export ImportAliasDeclaration
ExportDeclarationElement:
export InterfaceDeclaration export TypeAliasDeclaration export AmbientDeclaration export ImportAliasDeclarat
ion
ExportDefaultImplementationElement:
export default FunctionDeclaration export default GeneratorDeclaration export default ClassDeclaration exp
ort default AssignmentExpression ;
ExportDefaultDeclarationElement:
export default AmbientFunctionDeclaration export default AmbientClassDeclaration export default Identifier
Reference ;
ExportListDeclaration:
export * FromClause ; export ExportClause FromClause ; export ExportClause ;
ExportAssignment:
export = IdentifierReference ;
A.10 Ambientes
AmbientDeclaration:
declarar AmbientVariableDeclaration declarar AmbientFunctionDeclaration declarar AmbientClassDeclaration
declarar AmbientEnumDeclaration declarar AmbientNamespaceDeclaration
AmbientVariableDeclaration:
var AmbientBindingList ; deja AmbientBindingList ; const AmbientBindingList ;
AmbientBindingList:
AmbientBinding
AmbientBindingList , AmbientBinding
AmbientBinding:
BindingIdentifier TypeAnnotation opt
AmbientFunctionDeclaration:
function BindingIdentifier CallSignature ;
AmbientClassDeclaration:
clase BindingIdentifier TypeParameters ClassHeritage { AmbientClassBody }
opt
AmbientClassBody:
AmbientClassBodyElements opt
AmbientClassBodyElements:
AmbientClassBodyElement
AmbientClassBodyElements AmbientClassBodyElement
AmbientClassBodyElement:
AmbientConstructorDeclaration
AmbientPropertyMemberDeclaration
IndexSignature
AmbientConstructorDeclaration:
constructor ( ParameterList ) ;
opt
AmbientPropertyMemberDeclaration:
AccessibilityModifier estática PropertyName TypeAnnotation ; AccessibilityModifier
optar opt opt optar estática opt Property
Name CallSignature ;
AmbientEnumDeclaration:
EnumDeclaration
AmbientNamespaceDeclaration:
namespace IdentifierPath { AmbientNamespaceBody }
AmbientNamespaceBody:
AmbientNamespaceElements opt
AmbientNamespaceElements:
AmbientNamespaceElement
AmbientNamespaceElements AmbientNamespaceElement
AmbientNamespaceElement:
export AmbientVariableDeclaration export AmbientLexicalDeclaration export AmbientFunctionDeclaration e
opt opt opt
AmbientModuleDeclaration:
declare module StringLiteral { DeclarationModule }
1