Reduce type duplication in Motoko

Is there any way to extend the type without creating a new type containing similar properties as given in Typescript interfaces?
as an example, I have type like this

public type AuditRecord = {
        fileId: Text;
        action: Action;
        userId: Text;
        timestamp: ?Time.Time;
        organizationId: ?Text;

I wanted to create a new type with additional properties like

public type AuditOrgdto = {
        ...AuditRecord ,
      date: ?Text;

You can use type intersection:

type AuditOrgdto = AuditRecord and { date : ?Text };

I tried that but I’m getting this error

syntax error [M0001], unexpected token 'and', expected one of token or <phrase> sequence:
  ; seplist(<dec_field>,<semicolon>)
  . <id>
  -> <typ>

What version of Motoko are you using? This should work since 0.6.12 from last October.

My dfx version is dfx 0.8.4

Hm, apparently, SDK 0.8.4 still uses Motoko 0.6.11 by default. You should probably update your SDK to version 0.9.

1 Like

I upgrade the SDK. But I’m getting the same error.

It worked. I have to change the version of dfx in dfx.json because I used package vessel package manager. Really thanks for the help @rossberg.

It’s a little strange how I can easily declare a type intersection like this, but I can’t actually construct an object as easily.

For example, there’s no support for:


like there is in JS… right?

Yes, you are right. There is no spread operator in Motoko. But type intersection worked as expected for me.

posting here believing you guys might be able to help
Is there any way to do this?
I am having a type

public type DishType = { 
        name : Text;
        dishTypeId : Nat;
        parentDishTypeId : Nat;
        description: Text;

and my data is

record {3; record {parentDishTypeId=0; name="Main Course"; description=""; dishTypeId=3}};

Now if I want to update the name = "Main Course" field, what is the best way? How can i send only name to the backend? how can i make parameters optional? and how can i spread the name field to replace inside my api?

This is my code

public func updateDishtype (dishType : Types.DishType) : async Result.Result<Types.DishType, Types.Error> {
        let existingDishType = dishTypeRepository.getDishType(dishType.dishTypeId);
        switch(existingDishType) {
            case null {

            case (? v) {
                dishTypeRepository.upsertDishtype(dishType.dishTypeId, dishType);


This is the DishTypeRepository code

public class DishTypeRepository() {
    let dishTypesHashMap = HashMap.HashMap<Types.DishTypeId, Types.DishType>(0, isDishTypeIdEq, Hash.hash);

    public func upsertDishtype (dishTypeId : Types.DishTypeId, dishType : Types.DishType) {
      dishTypesHashMap.put(dishTypeId, dishType);

    public func getDishType(dishTypeId : Types.DishTypeId): ?Types.DishType {
      return dishTypesHashMap.get(dishTypeId);

It is coming: Field extensions/updates to existing objects by ggreif · Pull Request #3084 · dfinity/motoko · GitHub


The most exciting change since the BTC integration.

1 Like

Motoko devs when we get some sweet sugary syntax that will save us hundreds of lines of code.

Jack Nicholson Yes GIFs | Tenor


Thanks! As a quick heads-up I’ll just point to Release 0.7.0 · dfinity/motoko · GitHub, which contains the feature (and more :-). dfx will naturally lag a bit in picking this up, but if you are of the brave kind and want to give this a try, then feel free to download the binary. (And report back. Remember that .0 caveats apply!) We’ll do some broader messaging when it is readily available through the usual channels.

What does this mean? :grimacing:

Nothing nefarious, but the features are right out of the press and may contain minor bugs. We decided to jump from 0.6.30 to 0.7.0, so that people pay attention and file bug reports!

See also the middle paragraph in Upgrades and dot-zero versions - Michael Roach.

1 Like

In the Motoko Playground you can now take the 0.7.0 version to a test drive: Motoko Playground Update: Actor Classes are now enabled! - #4 by ggreif