paso - parametros por referencia typescript
¿Son las funciones fuertemente tipadas como parámetros posibles en TypeScript? (4)
En TypeScript, puedo declarar un parámetro de una función como una función de tipo. ¿Hay una forma "segura de escribir" de hacer esto que me estoy perdiendo? Por ejemplo, considera esto:
class Foo {
save(callback: Function) : void {
//Do the save
var result : number = 42; //We get a number from the save operation
//Can I at compile-time ensure the callback accepts a single parameter of type number somehow?
callback(result);
}
}
var foo = new Foo();
var callback = (result: string) : void => {
alert(result);
}
foo.save(callback);
La devolución de llamada guardada no es segura, le estoy dando una función de devolución de llamada donde el parámetro de la función es una cadena, pero le estoy pasando un número y compila sin errores. ¿Puedo hacer que el parámetro de resultado guarde una función de tipo seguro?
TL; versión DR: ¿hay un equivalente de un delegado de .NET en TypeScript?
Aquí están los equivalentes de TypeScript de algunos delegados comunes de .NET:
interface Action<T>
{
(item: T): void;
}
interface Func<T,TResult>
{
(item: T): TResult;
}
Me doy cuenta de que esta publicación es antigua, pero hay un enfoque más compacto que es ligeramente diferente al que se solicitó, pero puede ser una alternativa muy útil. Básicamente, puede declarar la función en línea al llamar al método (en este caso, save()
Foo
). Se vería algo como esto:
class Foo {
save(callback: (n: number) => any) : void {
callback(42)
}
multipleCallbacks(firstCallback: (s: string) => void, secondCallback: (b: boolean) => boolean): void {
firstCallback("hello world")
let result: boolean = secondCallback(true)
console.log("Resulting boolean: " + result)
}
}
var foo = new Foo()
// Single callback example.
// Just like with @RyanCavanaugh''s approach, ensure the parameter(s) and return
// types match the declared types above in the `save()` method definition.
foo.save((newNumber: number) => {
console.log("Some number: " + newNumber)
// This is optional, since "any" is the declared return type.
return newNumber
})
// Multiple callbacks example.
// Each call is on a separate line for clarity.
// Note that `firstCallback()` has a void return type, while the second is boolean.
foo.multipleCallbacks(
(s: string) => {
console.log("Some string: " + s)
},
(b: boolean) => {
console.log("Some boolean: " + b)
let result = b && false
return result
}
)
El enfoque multipleCallback()
es muy útil para cosas como llamadas de red que pueden tener éxito o fallar. Una vez más, asumiendo un ejemplo de llamada de red, cuando se llama multipleCallbacks()
, el comportamiento para un éxito y un fracaso se puede definir en un solo punto, lo que se presta a una mayor claridad para futuros lectores de código.
Generalmente, en mi experiencia, este enfoque se presta a ser más conciso, menos abarrotado y con mayor claridad en general.
¡Buena suerte a todos!
Por supuesto:
class Foo {
save(callback: (n: number) => any) : void {
callback(42);
}
}
var foo = new Foo();
var strCallback = (result: string) : void => {
alert(result);
}
var numCallback = (result: number) : void => {
alert(result.toString());
}
foo.save(strCallback); // not OK
foo.save(numCallback); // OK
Si lo desea, puede definir un tipo para encapsular esto:
type NumberCallback = (n: number) => any;
class Foo {
// Equivalent
save(callback: NumberCallback) : void {
callback(42);
}
}
type FunctionName = (n: returnType) => any;
class ClassName {
save(callback: FunctionName) : void {
callback(data);
}
}
Esto seguramente se alinea con el paradigma de programación funcional.