microsoft / microsoft/TypeScript
Allow structural typing of prototypes
Nessuno ha ancora preso questa issue.
- Lingua principale
- Go
- Stelle
- 111k
- Fork
- 14.3k
- Merge medio
- 2g 4h
- PR unite (30g)
- 132
Descrizione
### 🔍 Search Terms
prototype typing
prototype chain types
prototype inheritance
Object.create typing
inherited properties typing
### ✅ Viability Checklist
- [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
- [x] This wouldn't change the runtime behavior of existing JavaScript code
- [x] This could be implemented without emitting different JS based on the types of the expressions
- [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- [x] This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- [x] This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
### ⭐ Suggestion
> [!NOTE]
> I haven't been able to find a proposal that generalized problems encountered by typing prototypes structurally (searching is:issue in:title prototypes). Sorry if this is a duplicate.
This proposal introduces structural prototypes to TypeScript: a way to model the prototype of a value or type within the existing structural type system instead of treating prototype lookup as invisible to typing.
Core idea:
- every type has a prototype type
- prototype information composes structurally
- property lookup may include properties inherited through the prototype chain
- ownership and inheritance remain distinct in the type system
This feature is intended to improve typing of APIs and patterns that rely on prototypes, including `Object.getPrototypeOf`, `Object.setPrototypeOf`, `Object.create`, inherited members, and reflection utilities.
It does not attempt to add nominal typing, exact typing, or identity-based reasoning. It keeps prototypes structural.
## Motivation
JavaScript uses prototype inheritance at runtime, but TypeScript mostly types objects as if only their own declared properties existed. This creates a gap:
- values can expose inherited properties that are visible and usable at runtime
- `Object.getPrototypeOf` and related APIs cannot be described precisely, currently relying on extensive `any` usage.
- reflected information about ownership versus inheritance is mostly unavailable to the type system
- common operations such as reading inherited properties, walking prototypes, or setting prototypes are either under-typed or modeled loosely
Today TypeScript effectively flattens object behavior for most purposes while simultaneously pretending prototype structure is not part of the model. This proposal replaces that omission with an explicit structural model.
The intent is not to make prototypes nominal or identity-sensitive. The intent is to say: if JavaScript exposes prototype lookup structurally at runtime, TypeScript should be able to expose it structurally at compile time.
## Goals
- Model prototypes under current structural typing principles.
- Make the type of `Object.getPrototypeOf(x)` expressible.
- Preserve the distinction between own and inherited properties.
- Allow inherited properties to participate in ordinary property reads.
- Support more accurate typing for prototype-manipulating APIs.
- Keep the model compositional under unions, intersections, and recursion.
## Non-goals
- Nominal typing.
- Exact ownership tracking.
- Encoding prototype identity.
- Proving mutation stability of shared prototypes.
- Replacing or redefining JavaScript runtime behavior.
## Proposed syntax
Two new type operators are introduced.
### Unary prototype query
```ts
prototypeof T
```
This gives the prototype type associated with `T`.
### Infix prototype attachment
```ts
T prototype P
```
This produces a type with the same own properties as `T` and prototype type `P`.
This operator is right-associative:
```ts
T prototype P prototype Q
```
means:
```ts
T prototype (P prototype Q)
```
not:
```ts
(T prototype P) prototype Q
```
This matches JavaScript prototype chains.
## Core model
Every type `T` has two components:
- its own structure, written normally as `T`
- its prototype structure, written `prototypeof T`
These are both structural.
The type system distinguishes between:
- properties declared directly on `T`
- properties reachable through the prototype chain
The proposal introduces an implicit notion of apparent structure for property lookup.
## Apparent structure
Property reads in JavaScript walk the prototype chain. To model that, define an apparent form:
```ts
type Apparent = T & Apparent>>
```
with recursive expansion continuing until no new keys are introduced (e.g. `keyof prototypeof T extends never`).
> [!NOTE]
> `Apparent` and other helper types are used in this proposal. This proposal is *not* suggesting their integration as utility types.
- own properties are visible first
- prototype properties are visible if not shadowed by own properties
- inherited properties are treated as readonly views (see "Readonly inherited properties")
- deeper prototypes contribute recursively
This is not a source-level utility type. It is a specification device describing lookup semantics.
### Termination
The expansion stops when the next prototype layer contributes no new keys.
This fixed-point behavior handles:
- finite prototype chains
- self-reference such as `T prototype T`
- indirect cycles
- recursive prototype types
## Defaults
### Object types
For a plain object type declaration such as:
```ts
type Config = { port: number }
```
the default prototype is:
```ts
prototypeof Config = object | null
```
This means the type guarantees nothing about its prototype unless specified.
This is a deliberate abstraction boundary for object types.
`object | null` represents the "top type" of prototypes. All prototypes are be assignable to it.
A type `T prototype P` is only valid if `P` extends (is assignable to) `object | null`.
This means
```ts
type Proto = T prototype P // invalid
type Proto = T prototype P // correct
```
### Inferred values and literals
For values whose construction is known, the compiler may infer a more precise prototype.
For example:
```ts
const a = {}
```
may be inferred as:
```ts
{} prototype Object
```
(assuming `Object = typeof Object.prototype`, which is the case as of 5.9.3)
Likewise, other literals or known constructors may infer concrete built-in prototypes.
This separates: declared type-level abstraction from value-level inference of known constructors.
## Prototype types
### `never`
`prototypeof T` being `never` is appropriate for values such as `null` and `undefined`, for which `Object.getPrototypeOf` throws.
### `null`
`null` is a valid prototype value in JavaScript representing the absence of a prototype. A type may have `prototypeof T = null`, representing an object created with `Object.create(null)`, `Object.getPrototypeOf(Object.getPrototypeOf({}))`, or equivalent.
### `object`
`object` represents a prototype nothing is known about besides its existence.
### Primitive types
For primitive types, primitive values may infer prototypes when appropriate. For instance, `prototypeof number` is `Number`.
## Semantics of key operations
### Property access
A property access `t.x` type-checks if `x` exists in `Apparent`.
### Indexed access
Indexed access walks prototypes implicitly.
```ts
T[K]
```
is resolved against `Apparent`, preserving shadowing and readonly inherited members.
This ensures consistency between value-level reads and type-level indexed access:
- if `t.x` is readable, then `T["x"]` is meaningful
- inherited properties contribute to indexed access types
### `keyof`
`keyof` remains own-only.
```ts
keyof T
```
returns only keys declared directly on `T`, not inherited keys.
Rationale:
- preserves locality
- avoids far-away prototype changes affecting unrelated `keyof`s
- keeps mapped types predictable
- makes prototype-aware traversal explicit rather than implicit
Prototype-aware key traversal can be expressed separately.
### Mapped types
Mapped types operate on own keys only because they are driven by `keyof`.
This means mapped types do not implicitly preserve prototype structure unless explicitly reattached.
### Assignability
Assignability distinguishes between readable and writable requirements.
- Own properties satisfy both read and write requirements.
- Inherited properties (from the prototype chain) are treated as readonly:
- they can satisfy readonly property requirements
- they cannot satisfy mutable (writable) property requirements
This reflects JavaScript behavior:
- reading walks the prototype chain
- writing to an inherited property creates a new own property instead of mutating the prototype
#### Example
```ts
declare function f(x: { readonly a: string; b: number }): void
const x = Object.assign(Object.create({ a: "hi" }), { b: 440 })
f(x) // valid
```
This is valid because:
- `a` is available through the prototype chain and only required as `readonly`
- `b` is an own property
#### Invalid case
```ts
declare function f(x: { a: string; b: number }): void
const x = Object.assign(Object.create({ a: "hi" }), { b: 440 })
f(x) // error
```
This is rejected because:
- `a` is inherited
- the target type requires it to be writable
- writing would create a new own property, which is not guaranteed by the source type
## Readonly inherited properties
A property reached through the prototype chain is treated as readonly unless it is already an own property of the base type.
This is captured in the apparent form by applying `Readonly` to prototype contributions.
Rationale:
- reading inherited properties is normal JavaScript behavior
- writing through an inherited property often creates an own shadowing property instead of mutating the prototype
- making inherited members readonly avoids accidentally treating them as ordinary writable local properties
Example:
```ts
type T = {} prototype { a: number }
```
Then `T["a"]` behaves as a readonly property view.
This is a type-system safety rule. It does not claim that JavaScript runtime assignment is impossible; it prevents accidental confusion in the type model.
## Shadowing
Own properties shadow inherited properties by name.
Example:
```ts
type T = { a: string } prototype { a: number; b: boolean }
```
Then:
- `T["a"]` is `string`
- `T["b"]` is `readonly boolean`
The own declaration wins.
## Union and intersection behavior
Prototype information remains structural.
### Unions
```ts
type U = (A prototype P) | (B prototype Q)
```
Then:
```ts
prototypeof U = P | Q
```
and property lookup behaves as it normally does for unions.
### Intersections
```ts
type I = (A prototype P) & (B prototype Q)
```
This refines both own structure and prototype structure under normal structural rules.
The intended reading is not "multiple runtime prototypes", but "a type whose apparent contract satisfies both sides structurally".
## Recursive and cyclic prototypes
This proposal allows recursive prototype types.
Examples:
```ts
type Crazy = T prototype Crazy
```
and even degenerate forms such as:
```ts
T prototype T
```
These are valid if they stabilize under fixed-point apparent lookup.
For example, `Crazy` contributes no keys beyond those already in `T`, so its apparent structure stabilizes to `T`.
Likewise, indirect prototype cycles are tolerated as long as no new properties are introduced indefinitely.
The checker use the same kinds of cycle detection, caching, and recursion-limiting techniques already used for recursive types.
## Standard library typing examples
### `Object.getPrototypeOf`
```ts
declare function getPrototypeOf(obj: T): prototypeof T
```
### `Reflect.getPrototypeOf`
```ts
declare function getPrototypeOf(target: T): prototypeof T
```
### `Object.setPrototypeOf`
```ts
declare function setPrototypeOf(obj: T, proto: P): T prototype P
```
`setPrototypeOf` could also return `asserts obj is T prototype P` because it mutates `obj`.
Passing a non-object `proto` or `obj` doesn't throw (unlike stricter `Reflect.setPrototypeOf`) but it is a noop.
### `Reflect.setPrototypeOf`
```ts
declare function setPrototypeOf(obj: T, proto: P): T prototype P
```
### `Object.create`
```ts
declare function create
(proto: P): object prototype P
```
Additional overloads may model property descriptors and own members.
## Examples
### Basic attachment
```ts
type Parent = { host: string }
type Child = { port: number } prototype Parent
```
Then:
- `keyof Child` is `"port"`
- `prototypeof Child` is `Parent`
- `Child["host"]` is `readonly string`
- `Child["port"]` is `number`
### Shadowing
```ts
type T = { a: string } prototype { a: number; b: boolean }
```
Then:
- `T["a"]` is `string`
- `T["b"]` is `readonly boolean`
### Value inference
```ts
const x = Object.assign(Object.create({ a: 1 }), { b: 2 })
```
A possible inferred type is:
```ts
{ b: number } prototype { a: number }
```
### Prototype-aware assignability
```ts
declare function takesAB(x: { a: string; b: number }): void
const x = Object.assign(Object.create({ a: "hi" }), { b: 440 })
takesAB(x) // valid
```
### Prototype-aware readonly
```ts
type T = {} prototype { a: number }
declare let t: T
t.a // ok
t.a = 1 // error under inherited-readonly rule
```
## Rationale for own-only `keyof`
A major design choice is keeping `keyof` local.
If `keyof` walked prototype chains:
- it would no longer be a local operator
- mapped types would become prototype-sensitive by default
- nested prototype changes could invalidate distant code unexpectedly
- implementation and mental model complexity would increase significantly
By keeping `keyof` own-only:
- local structure remains simple
- prototype lookup is explicit where it matters
- mapped types remain predictable
- the only implicit prototype-walking operation is indexed access
This is a deliberate balance between fidelity and simplicity.
## Soundness considerations
This proposal does not attempt to solve all mutation unsoundness in JavaScript.
In particular:
- shared mutable prototypes can still change behind the type system's back
- prototype writes from external aliases remain possible
- runtime assignment to an inherited property may create an own property shadow instead of mutating the prototype
These are already part of JavaScript's behavior and align with existing TypeScript tradeoffs around mutability and aliasing.
Structural prototypes do not create a new category of unsoundness; they expose an existing runtime mechanism in a structured way.
The inherited-readonly rule reduces one common source of confusion without claiming full immutability.
## Why structural rather than nominal
A nominal design would attempt to preserve prototype identity or class lineage. That is not the direction of this proposal.
TypeScript already centers structural compatibility. Prototypes are therefore be modeled the same way:
- prototype information is a structural contract
- unions and intersections compose structurally
- apparent property lookup is structural
- no runtime identity assumptions are introduced
The proposal is intentionally minimal in this respect.
## Alternatives considered
### Ignore prototypes entirely
This is the status quo. It leaves reflection and prototype APIs under-typed and forces the checker to overlook a real source of properties.
### Make `keyof` walk prototypes
Rejected because it spreads prototype sensitivity too broadly and makes many local operations non-local.
### Preserve writable inherited properties
Rejected because it allows accidental, implicit property creation from mutation of prototype-origin members through flattened derived object aliases.
### Model prototypes nominally
Rejected because it conflicts with TypeScript's structural design and greatly increases complexity.
## Backwards compatibility
This proposal is largely additive.
Potential impacts include:
- more precise typing of inherited reads
- new readonly errors for inherited-only properties if value inference becomes prototype-aware
- improved typings for standard library reflection APIs
This design favors conservative defaults for declared object types to minimize disruption.
## Related issues (non exhaustive)
This proposal overlaps with several existing TypeScript issues, but is not identical to any one of them. Most existing discussions focus on one symptom at a time: typing specific prototype APIs, inherited property behavior, or gaps between JavaScript's runtime object model and TypeScript's structural model.
- #38385: discusses gaps in typing around prototype-manipulating APIs and highlights the lack of a first-class way to represent prototype relationships.
- #1108: early recognition that TypeScript’s structural model does not account for JavaScript’s prototype chain semantics, motivating a more faithful model.
- #22875: focuses on inconsistencies between property access and type queries, which your proposal addresses by making lookup explicitly prototype-aware.
- #32646: explores limitations in modeling inherited vs own properties, directly aligning with your ownership vs inheritance distinction.
- #37141: raises broader concerns about accurately modeling JavaScript object behavior, which this proposal systematizes through structural prototypes.
## Open questions
- How precisely should value inference attach concrete built-in prototypes? It is possible inferring too eagerly could break existing code, such behavior could be walled behind a new flag `strictPrototypeInference`.
- How should index signatures interact with inherited readonly lookup in detail?
- Which standard library APIs should be updated initially?
- Should there be syntax for prototype-aware key extraction in the standard library, or should such helpers remain user-defined?
## Conclusion
Structural prototypes extend TypeScript's existing structural model to a part of JavaScript it currently mostly ignores.
The key idea is:
- keep prototypes structural
- keep ownership distinct from inheritance
- allow property lookup to reflect runtime prototype reads
- preserve locality for most existing type operators
This approach improves precision for prototype-heavy code without forcing TypeScript into nominal or exact typing.
It does not reinvent JavaScript's object model. It simply stops pretending prototypes are absent.
### 📃 Motivating Example
[Playground link](https://www.typescriptlang.org/play/?#code/PTAEEFQBwJwewC6IJ5QKYFo4wJZoHYJoAmoAFmgDboyiU4BGMAhjMqAO64JH6g59sxAa3YApZgDdmAZQDGuKAlABnBMkpoAdACgdICNHhJ16UHAYArNHOUccCMqrKsSoBmheSc2HXLj4aqD4cMRoAArGcKAAvKAA3jqgyaAA1gLEAFygAOQhYTkANEkpOFmgGACMxSXJYSoKjGgAFI44Ktnx-OVquPgA5qAAvgCUCbUpyTBoCACuMHwABvlomQAk8W0qWmVDiwDcE0PFQ4emaKAAcqERUbGg53AAZsE3kYhwh-pgAERQKmhZsRorAPucfpxsKlWHBZvhSE9sA8yDhQGgAB7MAC2UE0+gAVPjgDpzhAoFBXIQADwAFQAfPcaaAAGSgABKaGYwPwlGQVIA8liHFTrmF3khCmk0MhnqB6XTDsAiSTUBdwOTKQhaQy4kzWeqKdNqRyuQFeQKhVrQSZVbKaZLUtK7XSXQTiQYAMLTZhEUDMUDSSizC72RzmDh8Yg+-3MeHOVyka0oMweLw+GAqswAVVFFziiUmZWyvQE-UOk3w2NWqgQfTLOlOeiVOhpoWYyElNNV8kUyix2AuSM0KhUdDgANHjguSdJAkRMCxPp8fAo010kF6s1s82YlAwM9VoH7YUooH8s0opDnaBgmT0-kCylmANvoBzNyMYMPWfFcB0yofIJnxvbIDU1Kl3zCHVQH5KwbAQLRmBHHB+nwZpYOsWwtAUTkiGaFZfxGSUC1KcoclmSoigmSssWrHJwCjKihlUJcVCePBR0gtARi+AwAEl8FXBw3G9YhRw4WFL3cC5zlISs5hYSheUzC4PUqRk0DUKkZCrKlHheYCYB2YhJRLAYXX2UADDgCNTJcYEOFHA90BU0APQAJg0rSdNovTbQMl8tBotBTNrUsLKssAbPwVyPQAZi8rUfLQPz0FlQytHSeFQrrCKDFEs12GaAQhKIYgRligAWRLtN0-TQAy+pGg8SVWhRDoEm6YswoGYYxhiBkzP6PKwBKm9hNIWjHFCJswAAIVmZQxu4NxaKxDwYFHVxQAKnl2G8NBHMlDgUTkJxFwQM7NNAMQZGkngQO+UAAAEEBUDAMXQWwPpgeAMwyrLSDiHJEFXHJFTAV73s++Cfr+nRGs05q81AZp+oZHJwdm8M+EdZBRzUdsxzkXc-TjWASBwWxmAYPFSSzF8AGlpVHOI8dlerDIh0AfjKCEAB8eeCn5sZOnBNH4eEMTcZg5DkTTRxJvg1HF09pieTRbEl0qRM5KNaYuNaNpUWKAFYauSqlWn8hqXxGABtHJAZyABdSVOcCwGLNigA2C3dOttKApvB2cia3APFd92bcRhoI7Qb2no5DX4OXCBwj40cPH8WijBsdoqHYWSCWVUlf3uXNf0VUvD3LuJnLQDmY5faviT8AIgiTbI65guCsP6GZf3OfknmaQyeNigB2f3fPqpNMoyHLwoVWKAA4Z5Sueoi0cOmlarZOi6ms6z62JBp64aV6e-kIxvFQUSgDAAUCBwcEkC5FvF1-ruzuBc8+6YyEDZ6DCHISg20nhwlsGnFwKgb74FpJKRmaJ0S8DEqAd4NB1DM2QHSZoFhLDZHtFKZA2RGYjDISgtBo52YvCZAAfgeDAYMoBsgMDgHATQsZua0PMHtUAA83qfmkLTdg0USHbAeNEaYYU0DvwkaAJ48AsTImnFEUkZ1mACCkXASUwESGyjAkaLU9J7wd2UHIAAnPcWB8Cx4vklHkKsOQJ6kg9NY3Umkkp1RtlY92zCE4KkijjbG7DOGcj4POZE7QAy7hYT6HacIEA4FopKbOzB9EcAuNyHIyhUghA4E9fJNlSyQgvKQaYABHWYOBpgoNlsoc4KhjqnScDE2EyhZQNDgGYKJWxPxQHHLuduj4zyVAAAw2KQnYwyjjnauMPGpSZnjvI+KDmM8ZaSOFcPwInAw4BkKoRpl-dQNZ2wE1rFuBSpMGCLR2ppL6QiuAOBphLSQo5loTR0KA8BdTIH4GgQEB4zBHQqBNPrTQuZmjokPrtXkaQMjdTrJZIsx9SmjGyJIOAZQvgIBBZpcFry0BQvHpZayqQQE2F+Rcf5gK+B4tBQAdW4ESqFMLOqAyRaWFFPQL59Uxdi4guL8UqGZS8g2JK7ZkrADeP62RAb8A+YJcaZVJQhE6RGDAzy8XANcjSLxtIqEEHQZchOjIziHktuAbcu5JQAFF0SPJINBe21q5i7hdka+Eo57YOqdcQT1jDmi+sdfBEgnqMTUNAK6m1lBA1MJYdkJ4u4ARjCTSmtA+wgA)
```ts
// A prototype-oriented helper library written in ordinary JavaScript style.
// A prototype object with shared behavior
const nodeProto = {
kind: 'node',
id: -1,
describe(this: { id: string }) {
return `node:${this.id}`;
},
};
type NodeProto = typeof nodeProto;
// "pseudo prototype" workaround for thi example
/**/
type Apparent = T & Readonly>;
/*/
type Apparent = T & Apparent>>
/*/
// Create a value with own data and shared prototype behavior
type UNode = {
id: string;
name: string;
};
/*
Today, TypeScript more or less loses the prototype information here.
A structural-prototype model could infer:
const user: UNode prototype UProto
*/
const user: Apparent = Object.assign(Object.create(nodeProto), {
id: 'u1',
name: 'Ada',
} satisfies UNode);
// Inherited reads would be typed naturally
type C1 = Test>; // own, shadows prototype
type C2 = Test>; // own
type C3 = Test>; // readonly (inherited)
type C4 = Test string>>; // inherited method
// But inherited members are readonly views, which matches JS better:
// @ts-expect-error
user.kind = 'other';
// @ts-expect-error
user.describe = () => '';
// own keys stay local and predictable
type UserKeys = keyof typeof user;
// "id" | "name"
// while indexed access can still reflect inherited readable members
type C5 = Test>;
type C6 = Test>;
// Reflection APIs become precisely typed
/**/
type Proto = NodeProto;
/*/
type Proto = prototypeof typeof user;
/*/
const proto: Proto = Object.getPrototypeOf(user);
type C7 = Test>;
type C8 = Test string>>;
// Ownership-sensitive utilities become expressible
declare function hasOwn(obj: T, key: K): K extends keyof T ? true : boolean;
// keyof only gets provably own keys. to retrieve keys from the prototype chain too, use keyof Apparent
const c9 = hasOwn(user, 'name');
type C9 = Test>; // own
// boolean for this value at runtime, because we don't know
// knowing would require exact types, which is out of scope for this proposal
const c10 = hasOwn(user, 'kind');
type C10 = Test>;
// Assignability stays structural but respects writable vs inherited
declare function takesReadableNode(x: { readonly kind: string; id: string }): void;
takesReadableNode(user); // ok
declare function takesWritableNode(x: { kind: string; id: string }): void;
takesWritableNode(user); // error: kind is inherited, not own-writable
type Test = T;
type Same = [Actual] extends [Expected] ? ([Expected] extends [Actual] ? true : false) : false;
```
### 💻 Use Cases
1. What do you want to use this for?*
I want to use this to type ordinary JavaScript code that builds objects through prototypes rather than classes, especially patterns involving `Object.create`, `Object.assign`, `Object.getPrototypeOf`, inherited property reads, and ownership-sensitive checks like `hasOwn`. The goal is to let TypeScript describe these values structurally, including both their own properties and the contract of their prototype, without introducing nominal classes or identity-based reasoning.
2. What shortcomings exist with current approaches?
Current TypeScript models these patterns weakly because prototype relationships are mostly invisible to the type system. Objects created through `Object.create` may expose inherited properties and methods at runtime, but TypeScript cannot describe that structure precisely. As a result, APIs like `Object.getPrototypeOf` and prototype-based object construction lose useful type information, inherited property reads are under-modeled, and the distinction between own and inherited properties is largely unavailable statically. TypeScript is strong at typing object literals and class instances, but much weaker at typing prototype-built objects even though JavaScript exposes them structurally.
3. What workarounds are you using in the meantime?
The current workaround is to manually flatten prototype information into ordinary object types, duplicate inherited members onto the apparent object shape, or fall back to loose typings such as `any`, broad object types, assertions, or custom helper types. In practice this means either losing precision or writing types that do not reflect the actual runtime structure, especially for `Object.create`, `Object.getPrototypeOf`, and inherited members.
Guida per i contributori
Apri la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Direzione di ricerca
Start by reviewing the proposed prototypeof and prototype attachment operators, apparent structure, shadowing, and recursive lookup rules. Then inspect the typing requirements for Object.getPrototypeOf, Reflect.getPrototypeOf, and Object.setPrototypeOf. Done means the design is resolved and the compiler and standard library consistently support the specified structural prototype behavior.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Valutazione
- Stack tecnologico
- javascript, typescript
- Ambito
- compilers
- Tipo di issue
- Funzionalità
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Stato di attività
- Tranquilla
- Chiarezza
- Abbastanza chiara
- Idoneità per principianti
- 25/100