Extending String native type in Typescript - oop

I would like to extend the String type in Typescript.
Here's my code :
export class Str extends String{
constructor(str: string) {
super(str);
}
}
The problem is, after the call of the String constructor using super(str), the value of my new type stills empty.
I have the same problem with another type extending the native Array type.

Your code is transpiled to:
var __extends = (this && this.__extends) || function (d, b) {
for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
var Str = (function (_super) {
__extends(Str, _super);
function Str(str) {
_super.call(this, str);
}
return Str;
})(String);
And the problem is that you no longer deal with the original native type that has special properties (like + operator on two strings). So your extended type - even if you would have succeded - would be severely limited and confusing for others.
Details and gotchas can be found Axel Rauschmayer's article: http://www.2ality.com/2013/03/subclassing-builtins-es6.html

Related

How can I use coalescing operator in Haxe?

As I mentioned in the question,
How can I use coalescing operator in Haxe?
Haxe does not have a null coalescing operator like C#'s ??.
That being said, it's possible to achieve something similar with macros. It looks like somebody has already written a library that does exactly this a few years ago. Here's an example from its readme:
var s = Sys.args()[0];
var path = s || '/default/path/to/../';
It uses the existing || operator because macros can not introduce entirely new syntax.
However, personally I would probably prefer a static extension like this:
class StaticExtensions {
public static function or<T>(value:T, defaultValue:T):T {
return value == null ? defaultValue : value;
}
}
using StaticExtensions;
class Main {
static public function main() {
var foo:String = null;
trace(foo.or("bar")); // bar
}
}
Instead of making your own, you could also consider using the safety library, which has a number of additional static extensions for Null<T> and features for dealing with null in general.
Use this addon:
https://github.com/skial/nco
Then, type
var value = a || 'backup value';
instead of
var value = (a == null) ? 'backup value' : a;
You can also utilize abstracts instead of macros for this purpose
class Test {
static function main() {
trace("Haxe is great!");
var s:Ory<String> = "hi!";
trace(s || "I don't get picked");
s = null;
trace(s || "I get picked");
trace(s + "!");
}
}
#:forward abstract Ory<T>(T) from T to T {
#:op(a||b) public inline function or(b:T):Ory<T> {
return this != null ? this : b;
}
}

Why Does Kotlin/JS Return Different Results for === Than Does Kotlin/JVM?

Given this code:
val value = "something"
println(value.toUpperCase().toLowerCase() == value) // prints true
println(value.toUpperCase().toLowerCase() === value) // prints false
On Kotlin/JVM 1.3.40, I get:
true
false
On Kotlin/JS 1.3.40, I get:
true
true
I would expect the same results on both, and I would expect the Kotlin/JVM results overall (as I should have different String objects).
Why am I getting different results based on runtime environment?
This is because of how the runtime handles it.
On the JVM, == maps to equals, and === maps to == (identity checking), as outlined here. Meanwhile, JavaScript's equals operators are weirder. If you decompile your code, you get this with JS:
kotlin.kotlin.io.output.flush();
if (typeof kotlin === 'undefined') {
throw new Error("Error loading module 'moduleId'. Its dependency 'kotlin' was not found. Please, check whether 'kotlin' is loaded prior to 'moduleId'.");
}
var moduleId = function (_, Kotlin) {
'use strict';
var equals = Kotlin.equals;
var println = Kotlin.kotlin.io.println_s8jyv4$;
function main(args) {
var value = 'something';
println(equals(value.toUpperCase().toLowerCase(), value)); // NOTE: equals
println(value.toUpperCase().toLowerCase() === value); // NOTE: ===
}
_.main_kand9s$ = main;
main([]);
Kotlin.defineModule('moduleId', _);
return _;
}(typeof moduleId === 'undefined' ? {} : moduleId, kotlin);
kotlin.kotlin.io.output.buffer;
Now, if you consider the equivalent Java code (slightly shortened and without Kotlin):
public static void main(String[] args){
String value = "something";
System.out.println(value.toUpperCase().toLowerCase().equals(value));
System.out.println(value.toUpperCase().toLowerCase() == value);
}
toUpperCase().toLowerCase() creates a new object, which breaks the == comparison, which is identity checking.
While === is outlined as identity checking as well, a === b is true if a and b are strings that contain the same characters. As you can tell from the decompiled Kotlin code, Kotlin.JS compiles to primitive Strings, not String objects. Because of that, the === in JS will return true when you're dealing with primitive strings.
In JavaScript there are both primitive strings and string objects (see e.g. "Distinction between string primitives and String objects" in https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String).
value.toUpperCase().toLowerCase() === value in Kotlin/JS compiles to value.toUpperCase().toLowerCase() === value in JavaScript (as you can verify by looking at the "Generated JavaScript code" tab at https://try.kotlinlang.org/). value.toUpperCase().toLowerCase() returns a primitive string. === on primitive strings is normal equality.

Properties in a module

Is there a way to define a property in a TypeScript module?
None of these compile:
module My {
// doesnt work
get Value(): number { return 42; }
// doesn't work either
get function Value(): number { return 42; }
// nope
function get Value(): number { return 42; }
}
Right now I'm forced to use this:
module My {
declare var Value: number;
Object.defineProperty(My, "Value", {
get: () => 42
});
}
The second form seems messy to me and the code hinting doesn't really treat it as a read-only property but as a plain variable.
Is there any standard way of defining properties directly inside modules?
No, there's not a way to declare a property on a module in TypeScript using any documented language features.
You can do it in several slightly round-about techniques.
A module can extend an existing class or function. So, I've created a class with a static property, and then later created a module that uses the same name as the class.
class My
{
static get Value():Number {
return 42;
}
}
module My {
var works: boolean = true;
}
alert(My.Value);
It does generate one oddity in the JavaScript generated code that you wouldn't do manually (and should be removed by most optimizers anyway) ... it will redeclare the variable My when the module is created. This does not cause a run-time issue as the variable was already lifted in JavaScript and will not conflict with the first usage.
Here's another option:
module Global {
class Inner {
get Value():Number {
return 42;
}
}
export var My;
My = new Inner();
}
var My = Global.My;
alert(My.Value);
While it presents an extra namespace, you can manipulate it however you'd like and use the inner class or change it as needed. This way, the My variable is global, just like it would be as a module.
Instead of using the module keyword, consider instead using export, which will allow you to do what you want to do, treating the file itself as a module (which is how CommonJS and AMD both work).
// in My.ts
var My = {
get value() {
return 42;
}
};
export = My;
// in foo.ts
import My = require('My');
console.log(My.value);
I describe this in greater detail in a blog post, The Definitive Guide to TypeScript.
I tried the singleton
let My = {
get value() {
return 42;
}
}
export My
but ran into an issue where the emitted JS still said get value() and didn't work on older versions of Node. I tried Object.defineProperty but then lost TypeScript compatibility. Here's my bridge that fixes both cases:
interface My {
value: number
}
// type assertion fixes TypeScript usage
let my = <My>{}
// defineProperty fixes JS usage
Object.defineProperty(my, 'value', {
get: () => 42
});
export = my;
It's used like a module in typescript
import * as my from './my'
my.property // returns 42
// my.property = doesn't work
I know it's a "little" late for this but using typescript 4.8 you can do this:
export module MyModule {
export var myVariable: string = "test";
}
then use it like:
MyModule.myVariable = "something else";

How to perform runtime type checking in Dart?

Dart specification states:
Reified type information reflects the types of objects at runtime and may always be queried by dynamic typechecking constructs (the
analogs of instanceOf, casts, typecase etc. in other languages).
Sounds great, but there is no instanceof-like operator. So how do we perform runtime type-checking in Dart? Is it possible at all?
The instanceof-operator is called is in Dart. The spec isn't exactly friendly to a casual reader, so the best description right now seems to be http://www.dartlang.org/articles/optional-types/.
Here's an example:
class Foo { }
main() {
var foo = new Foo();
if (foo is Foo) {
print("it's a foo!");
}
}
Dart Object type has a runtimeType instance member (source is from dart-sdk v1.14, don't know if it was available earlier)
class Object {
//...
external Type get runtimeType;
}
Usage:
Object o = 'foo';
assert(o.runtimeType == String);
As others have mentioned, Dart's is operator is the equivalent of Javascript's instanceof operator. However, I haven't found a direct analogue of the typeof operator in Dart.
Thankfully the dart:mirrors reflection API has recently been added to the SDK, and is now available for download in the latest Editor+SDK package. Here's a short demo:
import 'dart:mirrors';
getTypeName(dynamic obj) {
return reflect(obj).type.reflectedType.toString();
}
void main() {
var val = "\"Dart is dynamically typed (with optional type annotations.)\"";
if (val is String) {
print("The value is a String, but I needed "
"to check with an explicit condition.");
}
var typeName = getTypeName(val);
print("\nThe mirrored type of the value is $typeName.");
}
There are two operators for type testing: E is T tests for E an instance of type T while E is! T tests for E not an instance of type T.
Note that E is Object is always true, and null is T is always false unless T===Object.
Exact type matching is done via runtimeType property. Checking if an instance or any of its parent types (in the inheritance chain) is of the given type is done via is operator:
class xxx {}
class yyy extends xxx {}
void main() {
var y = yyy();
print(y is xxx);
print(y.runtimeType == xxx);
}
Returns:
true
false
Simply use .runtimeType on the property like below,
print(unknownDataTypeProperty.runtimeType)
Just to clarify a bit the difference between is and runtimeType. As someone said already (and this was tested with Dart V2+) the following code:
class Foo {
#override
Type get runtimeType => String;
}
main() {
var foo = Foo();
if (foo is Foo) {
print("it's a foo!");
}
print("type is ${foo.runtimeType}");
}
will output:
it's a foo!
type is String
Which is wrong.
Now, I can't see the reason why one should do such a thing...
T is The type
print( T.runtimeType)
if(value is int ) Returns true if the type of the value is int,
else if(value is! int )
To check the type of a variable use runtimeType
void main() {
int a = 10;
print(a.runtimeType);
}
to check whether the type of a variable is the same as your expected use is or runtimeType
void main() {
int a = 10;
print(a.runtimeType == int); // true
//or
print(a is int); // true
}
print("enter your phone number:\n");
var phone number = stdin.readLineSync();
if(phone number.runtimeType is int == true) // checks if the values input are integers
{
print('you have successfully input your phone number!');
}
else{
print('only numbers are allowed');
}

Trouble defining method for Javascript class definition

I'm somewhat new to object oriented programming in Javascript and I'm trying to build a handler object and library for a list of items I get back from an API call. Ideally, I'd like the library functions to be members of the handler class. I'm having trouble getting my class method to work however. I defined as part of the class bcObject the method getModifiedDateTime, but when I try to echo the result of the objects call to this method, I get this error:
Error on line 44 position 26: Expected ';'
this.getModifiedDateTime: function(epochtime) {
which leads me to believe that I simply have a syntax issue with my method definition but I can't figure out where.
response(
{
"items":
[
{"id":711,"name":"Shuttle","lastModifiedDate":"1268426336727"},
{"id":754,"name":"Formula1","lastModifiedDate":"1270121717721"}
],
"extraListItemsAttr1":"blah",
"extraListItemsAttr2":"blah2"
});
function response(MyObject) {
bcObject = new bcObject(MyObject);
thing = bcObject.getModifiedDateTime(bcObject.videoItem[0].lastModifiedDate);
SOSE.Echo(thing);
}
function bcObject(listObject) {
// define class members
this.responseList = {};
this.videoCount = 0;
this.videoItem = [];
this.responseListError = "";
// instantiate members
this.responseList = listObject;
this.videoCount = listObject.items.length;
// populate videoItem array
for (i=0;i<this.videoCount;i++) {
this.videoItem[i] = listObject.items[i];
}
this.getModifiedDateTime: function(epochtime) {
var dateStringOutput = "";
var myDate = new Date(epochtime);
dateStringOutput = myDate.toLocaleString();
return dateStringOutput;
};
}
You use = to assign values in JS, not ::
this.getModifiedDateTime = function(epochtime) {
You should use the = operator for methods defined as you did there (this.<methodName> = function (...) {).
The colon notation is used when declaring object literals.