Programming language: TypeScript 4.6 is more flexible with the constructor


The first beta of TypeScript 4.6 was released almost a week after the planned date. The release primarily brings changes under the hood aimed at better analysis of types. Also, it’s less strict with the constructor of child objects that call the constructor of the parent object.

TypeScript, like JavaScript, disallows access to in the constructor for a reason this before calling super(), since the parent class initializes the contents of the object there. However, Microsoft’s programming language has been arguably a little too strict with the rules, forbidding any code before calling the parent constructor, even if it doesn’t refer to the object itself this accesses.

This is changing with the current release after much preparatory work: The associated pull request is three years old and received a birthday cake shortly before implementation. With the implementation, code is now in front super allowed, with TypeScript making sure it doesn’t access the object through this contains.

The changes under the hood relate primarily to type assignment and testing. This is how the programming language derives the specific type when indexed access types are combined with a map for index access. So far it has assigned all types defined in the map as possible assignments, as the following example from the TypeScript blog shows:

interface TypeMap 
    "number": number;
    "string": string;
    "boolean": boolean;


type UnionRecord<P extends keyof TypeMap> =  [K in P]:
    
        kind: K;
        v: TypeMap[K];
        f: (p: TypeMap[K]) => void;
    
[P];

function processRecord<K extends keyof TypeMap>(record: 
                                                UnionRecord<K>) 
    record.f(record.v);


processRecord(
    kind: "string",
    v: "hello!",

    // 'val' used to implicitly have the type 
    // 'string )

Also, TypeScript 4.6 brings improved control flow analysis for dependent Rest parameters, where the type of a parameter depends on the one before it:

function func(...args: ["str", string] | ["num", number])

If the first parameter "str" is, the second is a string. If the first parameter but "num" is, the second is one number. TypeScript now uses this knowledge in further code and knows the type of the second parameter in blocks that check the first parameter, as in the following example from the TypeScript blog:

type Func = (...args: ["a", number] | ["b", string]) => void;

const f1: Func = (kind, payload) => 
    if (kind === "a") 
        payload.toFixed();  // 'payload' narrowed to 'number'
    
    if (kind === "b") 
        payload.toUpperCase();  // 'payload' narrowed to 'string'
    
;

f1("a", 42);
f1("b", "hello");

For deeper analysis of tools via using the --generateTraceflag, the team has released a trace analyzer that is available as a standalone project on GitHub.

Other innovations in the beta for version 4.6, such as improved checking of the depth of recursive instantiations, can be found on the TypeScript blog. The final release is scheduled for February 22nd.


(rm)

To home page



Source link -64