Structural typing is not duck typing
Asked Answered
A

2

5

As mentioned in TypeScript handbook:

One of TypeScript’s core principles is that type-checking focuses on the shape that values have. This is sometimes called “duck typing” or “structural subtyping”.In TypeScript, interfaces fill the role of naming these types,...


My understanding is, the above core principle does not relate to Duck typing but Structural typing, because TypeScript is static typed language.

As mentioned in wiki: It requires that type checking be deferred to runtime, and is implemented by means of dynamic typing or reflection... an object's suitability is determined by the presence of certain methods and properties (with appropriate meaning), rather than the actual type of the object.

How do I understand the above core principle of TypeScript?

Anastassia answered 1/5, 2018 at 14:18 Comment(6)
This is sometimes called "duck typing"... I don't see a claim that TypeScript is formally a Duck Typing system, per the strict definition, and a quick google search shows this statement to be true. TypeScript doesn't really fit into the wikipedia article because it's not a runtime language at all, it's just a type-checker. However it certainly meets several of the criteria, including the basic duck principal and the fact it compiles to JavaScript, a dynamically typed language.Jaffa
@Aaron type-checking focuses on the shapes that value have, is something to do with Structural typing but not Duck typing. Because my understanding of its meaning is... type compatibility and equivalence are determined by the type's actual structure or definition. Further in the handbook, it says the same... It’s worth pointing out that the type-checker does not require that these properties come in any sort of order, only that the properties the interface requires are present and have the required type.Anastassia
I think the definition you're using for duck-typing is not wrong, but not complete in how the term is used, which is why TypeScript is sometimes called "duck typing".Jaffa
@Aaron Due to type check in compile-time vs run-time, I see below example like this.. 1) let myObj:labelledValue = {size: 10, label: "Size 10 Object"}; has to go for compile-time type check, which follows structural typing. 2) Parameter object received in function printLabel(labelledObj: LabelledValue) {..} can only be checked at runtime, where there is no type(function printLabel(labelledObj) {}), so obviously it is the same rules that JS follows(duck typing), in second case.Anastassia
Yes, TS is "compile-time duck-typing" if you want to say.Jaffa
@Aaron I think the below answer should have let myObj = {size: 10, label_1: "Size 10 Object"};. Code still works dues to duck typing.Anastassia
P
6

From Duck test and Duck Typing and on Wikipedia

If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.

This is essentially how TypeScript interfaces work. An object just has to look like the interface rather than explicitly implement it.

Form the page you linked to:

interface LabelledValue {
    label: string;
}

function printLabel(labelledObj: LabelledValue) {
    console.log(labelledObj.label);
}

let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);

Even though myObj doesn't explicitly implement the LabelledValue interface it does have the same structure and therefore implicitly implements the interface. This is Duck Typing

UPDATE If the LabelledValue interface were defined as a class then the above code wouldn't "compile". This is Structural Typing.

Note TypeScript has no runtime checking as it is "compiled" down to JavaScript

Philcox answered 1/5, 2018 at 14:42 Comment(8)
1) Ducktyping does not require two objects to have same properties(of same type and name). Duck typing does not deal with type equivalence. For an object, If a property(say method) that you call, exist, then duck typing says you can call that method. 2) Structural typing(atleast in TypeScript) deals with type equivalence of two objects based on both type and names of the members in those two objectsAnastassia
Interfaces are a little different though. If an object has the same properties and types as defined in the interface then the object would be accepted as implementing the interface even though it isn't explicitly defined as such.Philcox
If LabelledValue was a class then that would change things. and myObj wouldn't pass the test and TypeScript would errorPhilcox
That is bad example, I would say, let myObj:labelledValue={...} then no more complications and you cannot call printLabel() anymore. This is one of the purpose of interface keyword, to solve such problems of JSAnastassia
In your answer: therefore implicitly implements the interface looks incorrect to me.Anastassia
True, you would normally explicitly specify the type, but, that isn't the point of the example. The example is there to show you how interfaces (and duck typing) work.Philcox
Isn't explicit typing & duck typing, mutually exclusive? Why language allow such constructs? to support 3rd part JS libraries?Anastassia
Let us continue this discussion in chat.Philcox
S
1
interface Duck {
    typing(): void;
}

const porky = {} as Duck;

try {
    porky.typing();
} catch (error) {
    console.log(error); // TypeError: porky.typing is not a function
}

const isDucky = (it: { typing?: () => void }): it is Duck =>
    typeof it.typing === 'function';

const daffy = {
    typing: () => console.log('tappity tap tap')
};

if (isDucky(daffy)) {
    daffy.typing(); // tappity tap tap
}

duck typing

Steffin answered 1/5, 2020 at 10:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.