Struct Embedding in TypeScript
// TypeScript supports composition through object spreading and
// interfaces, which can be used to achieve similar functionality
// to Go's struct embedding.
interface Base {
num: number;
describe(): string;
}
class BaseImpl implements Base {
constructor(public num: number) {}
describe(): string {
return `base with num=${this.num}`;
}
}
// A `Container` composes a `Base`. We use object spreading
// to include all properties of Base.
interface Container extends Base {
str: string;
}
function main() {
// When creating objects, we use object spreading to
// include all properties of the base object.
const co: Container = {
...new BaseImpl(1),
str: "some name"
};
// We can access the base's fields directly on `co`.
console.log(`co={num: ${co.num}, str: ${co.str}}`);
// We can also access the base's methods directly on `co`.
console.log("describe:", co.describe());
// TypeScript uses structural typing, so any object that has
// a `describe` method of the correct signature is considered
// to implement the `Describer` interface.
interface Describer {
describe(): string;
}
// `co` is automatically considered to implement `Describer`
// because it has a `describe` method.
const d: Describer = co;
console.log("describer:", d.describe());
}
main();
This TypeScript code demonstrates concepts similar to struct embedding in Go. Here’s an explanation of the key points:
We define a
Base
interface and aBaseImpl
class that implements it. This is similar to thebase
struct in the Go example.We create a
Container
interface that extendsBase
and adds an additionalstr
property. This is similar to thecontainer
struct in Go.When creating an object of type
Container
, we use object spreading (...new BaseImpl(1)
) to include all properties of the base object. This achieves a similar effect to Go’s struct embedding.We can access the base’s fields and methods directly on the
Container
object, just like in the Go example.TypeScript uses structural typing, which means that any object with a
describe
method of the correct signature is considered to implement theDescriber
interface. This is similar to how thecontainer
in Go automatically implemented thedescriber
interface.
To run this TypeScript code, you would typically use the TypeScript compiler (tsc
) to compile it to JavaScript, and then run the resulting JavaScript with Node.js. However, you can also use ts-node
to run TypeScript directly:
$ npm install -g ts-node typescript
$ ts-node struct-embedding.ts
co={num: 1, str: some name}
describe: base with num=1
describer: base with num=1
This example demonstrates how TypeScript can achieve similar functionality to Go’s struct embedding through its type system and object composition features.