Inheritance
Skittles supports contract inheritance using TypeScript's extends keyword.
Basic Inheritance
class BaseToken {
totalSupply: number = 0;
private balances: Record<address, number> = {};
balanceOf(account: address): number {
return this.balances[account];
}
}
class MyToken extends BaseToken {
name: string = "My Token";
override balanceOf(account: address): number {
// Custom implementation
return this.balances[account];
}
}
Generated Solidity
contract BaseToken {
uint256 public totalSupply;
mapping(address => uint256) internal balances;
function balanceOf(address account) public view virtual returns (uint256) {
return balances[account];
}
}
contract MyToken is BaseToken {
string public name = "My Token";
function balanceOf(address account) public view override returns (uint256) {
return balances[account];
}
}
When both parent and child are in the same file, Skittles generates both contracts in a single Solidity file with the is keyword for inheritance.
Virtual and Override
- All functions are
virtualby default, allowing child contracts to override them - Use the TypeScript
overridekeyword to mark a function as overriding a parent function
class Parent {
// Generated as: function getValue() public view virtual returns (uint256)
getValue(): number {
return 42;
}
}
class Child extends Parent {
// Generated as: function getValue() public view override returns (uint256)
override getValue(): number {
return 100;
}
}
Calling Super
Use super to call the parent implementation:
class Child extends Parent {
override getValue(): number {
let base: number = super.getValue();
return base + 1;
}
}
Interfaces (implements)
TypeScript implements is accepted for type checking but does not affect the Solidity output. It is a TypeScript compile time constraint only:
contracts/IToken.ts
import { address } from "skittles";
export default interface IToken {
name: string;
symbol: string;
decimals: number;
totalSupply: number;
balanceOf(account: address): number;
transfer(to: address, amount: number): boolean;
}
contracts/Token.ts
import IToken from "./IToken";
export class Token implements IToken {
// TypeScript ensures this class has all the required properties and methods
name: string = "My Token";
symbol: string = "MTK";
decimals: number = 18;
totalSupply: number = 0;
// ...
}
The implements keyword enforces the shape at the TypeScript level (giving you IDE autocomplete and error checking), while the generated Solidity is a standard contract without any interface import.