skip to Main Content

I have this code:

'use strict';

type Bar = 'a' | 'b';
type FooIntermidiate = {
  [p in Bar]: string;
};
type Foo = Required<FooIntermidiate>;

console.log(getFoo());

function getFoo(): Foo {
  const rv = Object.create(null);
  //const rv = {  };
  rv.b = 'str';
  return rv;
}

I expect the tsc to throw errors that at least the a property is missing on the returned value of type Foo. But this doesn’t happen. If I use the line: const rv = { }; then it throws, but about both of the props: a and b, which is better.

But why doesn’t it throw with the Object.create(null)?

It doesn’t matter if I use the Required<> type or not.

2

Answers


  1. Let’s look at Object.create() official definition:

        /**
         * Creates an object that has the specified prototype or that has null prototype.
         * @param o Object to use as a prototype. May be null.
         */
        create(o: object | null): any;
    
        /**
         * Creates an object that has the specified prototype, and that optionally contains specified properties.
         * @param o Object to use as a prototype. May be null
         * @param properties JavaScript object that contains one or more property descriptors.
         */
        create(o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any;
    

    As we can see, it has two overloadings, both accepting object | null. That’s why you don’t get the error when passing null. Both of the overloadings return any, so setting the property also doesn’t fire any error.

    Login or Signup to reply.
  2. Not sure your code makes a lot of sense: we don’t need Object.create here at all? Based on your comment thread, you can probably just declare your type, and then create your object with the as ThatType syntax, e.g:

    type CustomerRecord = {
        type: string,
        id: number,
        subsidiary: number,
    }
    
    function getUserDataFromDataBase(id: number): [string, number] {
        // let's pretend there is a database query happening here
        return [`customer`, 9];
    }
    
    function getRecord(id: number): CustomerRecord {
        const [type, subsidiary] = getUserDataFromDataBase(id);
        return { type, id, subsidiary} as CustomerRecord;
    }
    
    const record: CustomerRecord = getRecord(7);
    console.log(record);
    

    So you just create the plain JS object you need, and then you tell TypeScript that it needs to conform to the shape you declared. And if it doesn’t, TS will yell at you about not being able to unify your plain object with the type you declared. Like when you forget to add, or intentionally leave out, one of the three requires keys.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search