demo
demo

Reputation: 6235

Get field type in Typescript

I have class in Typescript. It has some fields

field1 : ko.observable<number>();
field2 : ko.observable<string>('');
...

In some function in another class I've tried to loop through every object field and for fields of type number I need to perform some modifications.

How can I detect this?


I've tried next, but always get type as string which is logically. locationModel filled with values from HTML form, where inputs is of type text

 Object.keys(locationModel)
 .forEach(property => {
                if (typeof locationModel[property]() === 'number') { }
                else{ }
            }
        });

Upvotes: 2

Views: 3094

Answers (2)

Tomalak
Tomalak

Reputation: 338248

If you want to put automatic type conversion into knockout you can create an extender for that.

In its most basic form it could return a writable computed that either:

  • converts the incoming value on write and stores the converted value in the observable, or
  • stores the incoming value in the observable unchanged and converts it on read.

An implementation of the latter could like this – run the snippet below and note how the type reflects in the viewmodel:

ko.extenders.type = function (target, type) {
    var typedValue = ko.pureComputed({
        read: function () {
            var value = target();
            if (typeof value === "undefined" || value === null) {
                return value;
            } else {
                return type(value);
            }
        },
        write: target
    });
    typedValue.raw = target;
    return typedValue;
};

var vm = {
    num: ko.observable().extend({type: Number}),
    str: ko.observable().extend({type: String})
};

ko.applyBindings(vm);

// init some values
vm.num(100);
vm.str(100);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

Num: <input data-bind="value: num"> (raw: <span data-bind="text: num.raw"></span>)<br>
Str: <input data-bind="value: str"> (raw: <span data-bind="text: str.raw"></span>)<br><br>

<hr>
View Model:<br>
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

Upvotes: 1

Alex
Alex

Reputation: 14503

Your problem is that input values from a form is always going to be strings, you have to parse the values properly to make them the type that you want.

So you'll need to manually set up some mapping that allows you to transform all input strings to the appropriate values in your model.

Upvotes: 0

Related Questions