Búsqueda de sitios web

javascript - Typescript: ¿cómo se define un tipo unión con booleano o una función de callback?


¿Cómo se establece un tipo unión para una función de callback o booleano? Lo intenté de esta manera, pero obtuve:

export interface IActions {
  dragend?: ((m:any)=>void) | boolean;
  click?:  ((m:any)=>void) | boolean;
  dblclick?:  ((m:any)=>void) | boolean;
}


    // using the following type guard in code
    // also tried `this.setting.click instanceof Function`
    if (typeof this.setting.click != 'boolean'){
      this.setting.click(m);
    } else {
      // default action
    }

Error :

error TS2349: No se puede invocar una expresión cuyo tipo carece de una firma de llamada. El tipo 'boolean | ((m: any) => void)' no tiene firmas de llamada compatibles.

Respuesta #1

Puedes usar guardias de tipo para crear declaraciones if que automáticamente tipan las variables por ti.

Una manera de escribir estos guardias sería:

(¡Perdona el nombre... hoy no me siento muy creativo!)

type Action = (m: any) => void;
type ActionOrBoolean = Action | boolean;

function isActionOrBooleanAction(actionOrBoolean: ActionOrBoolean): actionOrBoolean is Action {
    return typeof actionOrBoolean != 'boolean';
}

function isActionOrBooleanBoolean(actionOrBoolean: ActionOrBoolean): actionOrBoolean is boolean {
    return typeof actionOrBoolean == 'boolean';
}

Y se pueden usar así:

let v3: ActionOrBoolean = (Math.random() > 0.5)
  ? (p1: any) => {}
  : true;

if(isActionOrBooleanBoolean(v3)) {
    v3 = false;
} else if(isActionOrBooleanAction(v3)) {
    v3("");
}

Finalmente, aquí hay un jsFiddle que muestra todo funcionando.

writeLine("v1: " + v1);
writeLine("v1 isActionOrBooleanAction: " + isActionOrBooleanAction(v1));
writeLine("v1 isActionOrBooleanBoolean: " + isActionOrBooleanBoolean(v1));

writeLine("v2: " + v2);
writeLine("v2 isActionOrBooleanAction: " + isActionOrBooleanAction(v2));
writeLine("v2 isActionOrBooleanBoolean: " + isActionOrBooleanBoolean(v2));

// Example
let v3: ActionOrBoolean = (Math.random() > 0.5)
  ? (p1: any) => {}
  : true;

if(isActionOrBooleanBoolean(v3)) {
    v3 = false;
} else if(isActionOrBooleanAction(v3)) {
    v3("");
}

Salida :

v1: verdadero

v1 esAcciónOAcciónBooleana: falso

v1 esAcciónOBooleanoBooleano: verdadero

v2: función (p1) { }

v2 esAcciónOAcciónBooleana: verdadero

v2 esAcciónOBooleanoBooleano: falso