Es hört sich so an, als ob Sie möchten, dass der Objektparameter optional ist und auch jede der Eigenschaften des Objekts optional ist. In dem Beispiel ist die Überladungssyntax nicht erforderlich. Ich wollte auf einige schlechte Praktiken in einigen der Antworten hier hinweisen. Zugegeben, es ist nicht der kleinstmögliche Ausdruck, im Wesentlichen zu schreiben box = { x: 0, y: 87, width: 4, height: 0 }
aber dies bietet alle Code-Hinweise, die man sich von der beschriebenen Klasse wünschen kann. In diesem Beispiel können Sie eine Funktion mit one, some, all aufrufen, ou keinen der Parameter und erhalten trotzdem Standardwerte.
/** @class */
class Box {
public x?: number;
public y?: number;
public height?: number;
public width?: number;
constructor(params: Box = {} as Box) {
// Define the properties of the incoming `params` object here.
// Setting a default value with the `= 0` syntax is optional for each parameter
let {
x = 0,
y = 0,
height = 1,
width = 1
} = params;
// If needed, make the parameters publicly accessible
// on the class ex.: 'this.var = var'.
/** Use jsdoc comments here for inline ide auto-documentation */
this.x = x;
this.y = y;
this.height = height;
this.width = width;
}
}
Müssen Sie Methoden hinzufügen? Eine ausführliche, aber besser erweiterbare Alternative: Die Box
Klasse als Schnittstelle verwendet werden, da sie identisch sind. Wenn Sie die obige Klasse ändern wollen, müssen Sie eine neue Schnittstelle für das Objekt incoming parameters definieren und referenzieren, da die Box
Klasse nicht mehr genau wie die Eingangsparameter aussehen würde. Beachten Sie, wo die Fragezeichen ( ?:
), die optionale Eigenschaften bezeichnen, bewegen sich in diesem Fall. Da wir innerhalb der Klasse Standardwerte festlegen, sind sie garantiert vorhanden, aber im Objekt der eingehenden Parameter optional:
interface BoxParams {
x?: number;
// Add Parameters ...
}
class Box {
public x: number;
// Copy Parameters ...
constructor(params: BoxParams = {} as BoxParams) {
let { x = 0 } = params;
this.x = x;
}
doSomething = () => {
return this.x + this.x;
}
}
Unabhängig von der Art und Weise, wie Sie Ihre Klasse definieren, bietet diese Technik die Leitplanken der Typensicherheit, aber auch die Flexibilität, jedes dieser Elemente zu schreiben:
const box1 = new Box();
const box2 = new Box({});
const box3 = new Box({x:0});
const box4 = new Box({x:0, height:10});
const box5 = new Box({x:0, y:87,width:4,height:0});
// Correctly reports error in TypeScript, and in js, box6.z is undefined
const box6 = new Box({z:0});
Kompiliert sehen Sie, wie die Standardeinstellungen nur verwendet werden, wenn ein optionaler Wert undefiniert ist; dies vermeidet die Fallstricke einer weit verbreiteten (aber fehleranfälligen) Fallback-Syntax von var = isOptional || default;
durch Abgleich mit void 0
was eine Abkürzung ist für undefined
:
Die kompilierte Ausgabe
var Box = (function () {
function Box(params) {
if (params === void 0) { params = {}; }
var _a = params.x, x = _a === void 0 ? 0 : _a, _b = params.y, y = _b === void 0 ? 0 : _b, _c = params.height, height = _c === void 0 ? 1 : _c, _d = params.width, width = _d === void 0 ? 1 : _d;
this.x = x;
this.y = y;
this.height = height;
this.width = width;
}
return Box;
}());
Addendum: Einstellung von Standardwerten: der falsche Weg
Les ||
(oder) Betreiber
Bedenken Sie die Gefahr von ||
/oder Operatoren bei der Festlegung von Standardrückfallwerten, wie in einigen anderen Antworten gezeigt. Der folgende Code veranschaulicht die falsche Art, Standardwerte zu setzen. Sie können unerwartete Ergebnisse erhalten, wenn Sie gegen falsch Werte wie 0, '', null, undefiniert, falsch, NaN:
var myDesiredValue = 0;
var result = myDesiredValue || 2;
// This test will correctly report a problem with this setup.
console.assert(myDesiredValue === result && result === 0, 'Result should equal myDesiredValue. ' + myDesiredValue + ' does not equal ' + result);
Object.assign(this,params)
In meinen Tests mit es6/typescript destrukturiertes Objekt kann 15-90% schneller sein als Object.assign . Die Verwendung eines destrukturierten Parameters erlaubt nur Methoden und Eigenschaften, die Sie dem Objekt zugewiesen haben. Nehmen wir zum Beispiel diese Methode:
class BoxTest {
public x?: number = 1;
constructor(params: BoxTest = {} as BoxTest) {
Object.assign(this, params);
}
}
Wenn ein anderer Benutzer kein TypeScript verwendet und versucht, einen Parameter zu platzieren, der nicht dazugehört, könnte er beispielsweise versuchen, ein z
Eigenschaft
var box = new BoxTest({x: 0, y: 87, width: 4, height: 0, z: 7});
// This test will correctly report an error with this setup. `z` was defined even though `z` is not an allowed property of params.
console.assert(typeof box.z === 'undefined')