Soy bastante nuevo en TypeScript y me gustaría saber si existe una buena manera de reescribir el código para evitar el error TSLint "el acceso al objeto a través de cadenas literales no está permitido" en el siguiente código
interface ECType
{
name: string;
type: string;
elementType?: string;
}
export var fields: { [structName: string]: Array<ECType>; } = { };
class ECStruct1 {
foo: string;
bar: number;
baz: boolean;
qux: number;
quux: number;
corge: ECStruct2[];
grault: ECStruct2;
constructor() {
...
}
}
fields['ECStruct1'] = [
{ name: 'foo', type: 'string' },
{ name: 'bar', type: 'int' },
{ name: 'baz', type: 'bool' },
{ name: 'qux', type: 'long' },
{ name: 'quux', type: 'ulong' },
{ name: 'corge', type: 'array', elementType: 'ECStruct2' },
{ name: 'grault', type: 'ECStruct2' }
];
Actualización : Al final, el contenido anterior será parte de un archivo autogenerado con más de 300 ECStruct
s, por lo que me gustaría tener la definición de la clase (por ejemplo ECStruct1
) seguida de su metadescripción (por ejemplo fields['ECStruct1']
).
typescript
tslint
Denis Cappellin
fuente
fuente
fields['ECStruct1']
porfields.ECStruct1
. Por lo general, se prefiere el uso de la notación de puntos para acceder a los accesorios de los objetos al acceso literal de cadena.fields.ECStruct1=
el compilador TS no lo permite: Error TS2339 La propiedad 'ECStruct1' no existe en el tipo '{[structName: string]: ECType []; } '.Respuestas:
Tienes un par de opciones aquí:
Solo deshabilita la regla
/* tslint:disable:no-string-literal */ whatever.codeHere() /* tslint:enable:no-string-literal */
Usa una variable en lugar de una cadena literal
// instead of fields['ECStruct1'] = ... // do something like let key = 'ECStruct1'; fields[key] = ...
Escribir / generar una interfaz explícita
Vea la respuesta de MartylX arriba . Esencialmente:
interface ECFieldList { ECStruct1: ECType[]; } export var fields:ECFieldList = { ECStruct1: [ ...
Cualquiera de estas son soluciones razonables, aunque no soy tan fan del # 2 porque está alterando tu código sin una buena razón. Si está generando código de todos modos, quizás generar un tipo
fields
como en el n. ° 3 sea una buena solución.fuente
Puedes deshacerte de la regla. Busque
tslint.json
, el agregar una propiedad"no-string-literal"
confalse
, enrules
:{ "rules": { "no-string-literal": false, ... other rules ...
fuente
Simplemente use la anotación literal de plantilla.
fields[`ECStruct1`]
fuente
¿Y de esta manera? No sé si necesita el indexador (
[structName: string]: Array<ECType>;
) o no.interface ECType { name: string; type: string; elementType?: string; } interface ECFieldList { ECStruct1: ECType[]; } export var fields:ECFieldList = { ECStruct1: [ {name: 'foo', type: 'string'}, {name: 'bar', type: 'int'}, {name: 'baz', type: 'bool'}, {name: 'qux', type: 'long'}, {name: 'quux', type: 'ulong'}, {name: 'corge', type: 'array', elementType: 'ECStruct2'}, {name: 'grault', type: 'ECStruct2'} ] };
fuente
interface
con N deECStruct
y luegoexport var fields...
dónde escribo la definición real de cadaECStruct
.no-string-literal
(no permite el acceso a objetos a través de literales de cadena. - npmjs.com/package/tslint )no-string-literal
habilitada globalmente y solo en el archivo con el código anterior la deshabilité con comentario/* tslint:disable: no-string-literal */
.fields[variable]
) y la sintaxis de puntos con cadenas (es decirfields.ECStruct1
) y debería estar bien.Probablemente no sea la mejor opción, pero usar
fields['ECStruct1'.toString()]
funciona tambien
fuente
Una forma sencilla es definir una variable para contener el valor de ECStruct1:
const sampleName = 'ECStruct1';
y luego, obtenga acceso al objeto usando la variable como índice:
fuente