0

I was hoping for a little guidance for jsligo. I am writing a simple contract that I am trying to make into a teaching tool. However I am stuck trying to pass a partial object to an entrypoint.

type full_name = [string, string]; // first name last name

type person = {
  age: int, 
  full_name: full_name,
  is_cool: bool,
  nationality: string,
};

const setPerson = (person: person, store: storage): storage => {
  const {full_name, age, nationality, is_cool} = person;
  const updated_person = {...store.person, full_name, age, nationality, is_cool};
  return { ...store, person: updated_person };
}

Ideally I would be able to pass a partial of person to the setPerson however I am unsure how to make the key value pairs of person optional and then check them in the function.Anyone have any ideas if this is possible? is there anything similar to TS Partial<> type if not I can just adjust the structure to something that may be more fitting.Thanks in advance for any help!

1 Answer 1

0

I don't know what Partial<> does, but I guess the closest thing you could have is setting some fields of your record to option:

type person = {
  age: int,
  full_name: full_name,
  is_cool: option<bool>,
  nationality: option<string>,
};

It isn't clear what you want to update in your person, but let's say that you want to enforce that a person that is registered in your contract is cool. Then no matter what the value of the field is in the first place, you can do:

const setPerson = (person: person, store: storage): storage => {
  const {full_name, age, nationality, is_cool} = person;
  const updated_person = {...store.person, full_name, age, nationality, is_cool: Some(true)};
  return { ...store, person: updated_person };
}

Values of the type option<bool> can be Some(true), Some(false) or None to indicate the absence of a value. However you have to use the Some constructor every time, which can be cumbersome.Instead of doing that, a common pattern in functional languages is to define pre- types that only contain the fields you're sure to have at some point of the execution. That way, you can make sure that the data you manipulate under a given name (such as person) always have all the information you need, as the typechecker won't let you define incomplete records. This gives

type pre_person = {
  age: int,
  full_name: full_name,
};

type person = {
  age: int,
  full_name: full_name,
  is_cool: bool,
  nationality: string,
};

const setPerson = (pre_person: pre_person, store: storage): storage => {
  const person = {
    full_name: pre_person.full_name,
    age: pre_person.age,
    nationality: "tezonian",
    is_cool: true
  };
  return { ...store, person };
}

and you can even add some arguments to setPerson, e.g., nationality: option<string>.

3
  • Thank you for the help! That thoroughly answered my question! > as the typechecker won’t let you define incomplete records, this is exactly what the Partial<> in typescript is. You can specify which parts of a record are mandatory and which are possibly undefinedI am thinking too much in the way of Typescript to do some heavy lifting that I need to stop using.
    – user9011
    Jun 12, 2023 at 14:17
  • option is the current workaroundWe discussed around type composition to do union and intersection of types but it is not yet available on Ligo. It might look like Typescript implementation.
    – user9011
    Jun 12, 2023 at 14:17
  • Thank you. I think I got it to work in something similar to what I was aiming for trying to figure out how Taquito can use it or make it more simple for users. Hoping to make a simple dApp to show how to handle different entry points and needs of a contract. I might aim to write an article for these type of nuances and differences between ligo and typescript.
    – user9011
    Jun 12, 2023 at 14:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.