Soy nuevo en TypeScript y estoy tratando de definir una clase similar a una enumeración con algunos atributos adicionales. He visto que hay dos enfoques diferentes para hacer esto:
export class AwsRegion { public static US_EAST_1 = new AwsRegion('us-east-1'); public static EU_WEST_1 = new AwsRegion('eu-west-1'); public static US_WEST_2 = new AwsRegion('us-west-2'); private name: string; constructor(name: string) { this.name = name; } public getName(): string { return this.name; } } export interface AwsRegion { readonly name: string; } export const US_EAST_1: AwsRegion = { name: 'us-east-1' }; export const EU_WEST_1: AwsRegion = { name: 'eu-west-1' }; export const US_WEST_2: AwsRegion = { name: 'us-west-2' };¿Hay alguna ventaja para cualquiera de los dos, o uno que es más idiomático en mecanografiado que el otro?
Gracias,
Typescript admite muchos estilos de programación. Para tener una idea de los modismos que el equipo de AWS eligió para CDK, consulte el código fuente de CDK en github . El código fuente del paquete lambda es un buen lugar para comenzar.
El CDK a menudo usa métodos estáticos de fábrica para la configuración:
export class Runtime { // ... public static readonly NODEJS_14_X = new Runtime('nodejs14.x', RuntimeFamily.NODEJS, { supportsInlineCode: true }); public static readonly PYTHON_2_7 = new Runtime('python2.7', RuntimeFamily.PYTHON, { supportsInlineCode: true }); Con respecto a sus ejemplos, tenga en cuenta que, tal como está escrito, ambos enfoques permiten a las personas que llaman crear objetos de configuración no válidos. Typescript aceptará mars como una región sin quejarse:
// class const mars: AwsRegion = new AwsRegion('mars'); // plain old object const MARS_REGION: AwsRegion = { name: 'mars' };Puedes arreglar esto. Para el enfoque de clase: haga que el constructor sea privado.
private constructor(name: string) {} // TS Error: Constructor of class 'AwsRegion' is private and only accessible within the class declaration const mars: AwsRegion = new AwsRegion("mars")Para la versión POJO, restrinja las regiones válidas en la interfaz
interface AwsRegion { readonly name: 'us-east-1' | 'eu-west-1' | 'us-west-2'; } // TS Error: Type '"mars"' is not assignable to type '"us-east-1" | "eu-west-1" | "us-west-2"' const MARS_REGION: AwsRegion = { name: 'mars' };Aquí está la versión de código en vivo de TS Playground de estos ejemplos.