diff --git a/docs/advanced/compiler-annotations.md b/docs/advanced/compiler-annotations.md
index 67fe10e5..220085a7 100644
--- a/docs/advanced/compiler-annotations.md
+++ b/docs/advanced/compiler-annotations.md
@@ -416,7 +416,7 @@ NoSelfNS.noSelfFunc("bar")
-For more information about how the `self` parameter is handled, see [Functions and the `self` Parameter](functions-and-the-self-parameter.md)
+For more information about how the `self` parameter is handled, see [Functions and the `self` Parameter](../the-self-parameter.md)
## @noSelfInFile
diff --git a/docs/advanced/functions-and-the-self-parameter.md b/docs/advanced/functions-and-the-self-parameter.md
deleted file mode 100644
index de3d646f..00000000
--- a/docs/advanced/functions-and-the-self-parameter.md
+++ /dev/null
@@ -1,234 +0,0 @@
----
-title: Functions and the `self` Parameter
----
-
-import { SideBySide } from "@site/src/components/SideBySide";
-
-## Every Function Has a Context Parameter
-
-In JavaScript and TypeScript, almost all functions have access to an implicit `this` parameter. In order to maintain compatibility with this, all Lua functions are generated with an extra initial context parameter.
-
-**Example**
-
-
-
-```typescript
-function myFunction(arg: string) {}
-myFunction("foo");
-```
-
-```lua
-function myFunction(self, arg)
-end
-myFunction(nil, "foo")
-```
-
-
-
-The reason for this is that a method can be assigned to a stand-alone function and vice-versa.
-
-**Example**
-
-```typescript
-class MyClass {
- myMethod(arg: string) {
- console.log("myMethod", arg);
- }
-}
-
-let myFunction = function (arg: string) {
- console.log("myFunction", arg);
-};
-
-const c = new MyClass();
-
-c.myMethod = myFunction;
-c.myMethod("foo"); // should output: myFunction foo
-// or
-myFunction = c.myMethod;
-myFunction("foo"); // should output: myMethod foo;
-```
-
-If `myFunction` did not have the initial parameter, calling either after being re-assigned would cause potential runtime errors, since `myMethod` would expect an initial parameter and `myFunction` would not.
-
-Note that even declared functions are assumed to have this extra parameter as well.
-
-**Example**
-
-
-
-```typescript
-declare function myLibFunction(arg: string): void;
-myLibFunction("foo");
-```
-
-```lua
-myLibFunction(nil, "foo")
-```
-
-
-
-## Removing the Context Parameter
-
-When dealing with external library functions that don't expect this initial parameter, you will need to inform TypeScriptToLua. This can be done a few different ways.
-
-### `this: void`
-
-You can declare any function with `this: void` to prevent generation of this initial argument.
-
-**Example**
-
-
-
-```typescript
-declare function myLibFunction(this: void, arg: string): void;
-myLibFunction("foo");
-```
-
-```lua
-myLibFunction("foo")
-```
-
-
-
-This works on methods as well, which can be useful if you have class methods which should be called with a dot `.` instead of a colon `:`.
-
-**Example**
-
-
-
-```typescript
-declare class MyClass {
- withContext(arg: string): void;
- withoutContext(this: void, arg: string): void;
-}
-const c = new MyClass();
-c.withContext("foo");
-c.withoutContext("foo");
-```
-
-```lua
-local c = __TS__New(MyClass)
-c:withContext("foo") -- uses colon :
-c.withoutContext("foo") -- uses dot .
-```
-
-
-
-Another common scenario is a library function which takes a lua callback function, which should not have a context parameter.
-
-**Example**
-
-
-
-
-```typescript
-declare function takesCallback(
- this: void,
- callback: (this: void, arg: string) => void,
-): void;
-
-takesCallback(arg => {
- console.log(arg);
-});
-```
-
-```lua
-takesCallback(function(arg) print(arg) end)
-```
-
-
-
-### `@noSelf`
-
-If you wish to specify that all functions in a class, interface or namespace should not have a context parameter, you can use the [`@noSelf`](compiler-annotations.md#noself) annotation.
-
-**Example**
-
-
-
-```typescript
-/** @noSelf **/
-declare namespace MyNamespace {
- function myFunction(arg: string): void;
-}
-MyNamespace.myFunction("foo");
-```
-
-```lua
-MyNamespace.myFunction("foo")
-```
-
-
-
-You can override `@noSelf` on a per-function basis by specifying a `this` parameter.
-
-**Example**
-
-
-
-```typescript
-/** @noSelf **/
-declare namespace MyNamespace {
- function myFunction(this: any, arg: string): void;
-}
-MyNamespace.myFunction("foo");
-```
-
-```lua
-MyNamespace:myFunction("foo")
-```
-
-
-
-### `@noSelfInFile`
-
-If you want to specify that all functions in a file should have no context, you can use [`@noSelfInFile`](compiler-annotations.md#noselfinfile) at the top of the file.
-
-For more information on [`@noSelf`](compiler-annotations.md#noself) and [`@noSelfInFile`](compiler-annotations.md#noselfinfile), please refer to [Compiler Annotations](compiler-annotations).
-
-## Assignment Errors
-
-Functions that have a context parameter cannot be assigned to functions that do not, and vice-versa. A common case where this may occur is passing a callback to an api that expects a function that does not take an initial argument.
-
-**Example**
-
-```ts
-declare function takesCallback(callback: (this: void, arg: string) => void);
-
-function myCallback(arg: string) {}
-takesCallback(myCallback); // Error: Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'.
-```
-
-This throws an error because if `takesCallback` called `myCallback`, it would do so without passing an initial context parameter. This can be easily fixed simply by wrapping the call in an arrow function.
-
-**Example**
-
-
-
-```typescript
-takesCallback((arg) => myCallback(arg));
-```
-
-```lua
-takesCallback(function(arg) return myCallback(nil, arg) end)
-```
-
-
-
-The reason this works is because TypeScriptToLua infers whether the arrow function should take a context parameter or not based on the type it's being assigned to.
-
-### Overloads
-
-If a function is overloaded and the signatures differ in context type, you can not assign them:
-
-```ts
-declare function takesFunction(f: Function): void;
-
-declare function myFunction(this: void, s: string, n: number): void;
-declare function myFunction(s: string);
-
-takesFunction(myFunction); // Error: Unsupported assignment of function with different overloaded types for 'this'. Overloads should all have the same type for 'this'.
-```
-
-It's best practice to avoid overloads with different context types.
diff --git a/docs/the-self-parameter.md b/docs/the-self-parameter.md
new file mode 100644
index 00000000..508fdf3d
--- /dev/null
+++ b/docs/the-self-parameter.md
@@ -0,0 +1,255 @@
+---
+title: The Self Parameter
+---
+
+import { SideBySide } from "@site/src/components/SideBySide";
+
+## Why is it there by default
+
+All functions, by default, have a `self` parameter to preserve JavaScript behaviour.
+
+Telling TypeScript not to allow `this` to be used will eliminate that parameter from its containing context.
+
+Other workarounds are available for removing this too.
+
+> Disabling this self parameter should mainly be done when writing declarations for Lua interop purposes.
+
+## Removing it
+
+### `this: void`
+
+This is a type-safe solution usable whenever describing something callable.
+
+This tells TypeScript that `this` cannot be used in the context of this function.
+
+`this: void` results in no `self` parameter to be generated.
+
+**Example**
+
+
+
+```typescript
+declare function f(this: void, arg: string): void;
+f("foo");
+```
+
+```lua
+f("foo")
+```
+
+
+
+Also useful if you have class methods which should be called with a dot `.` instead of a colon `:`.
+
+**Example**
+
+
+
+```typescript
+declare class Class {
+ colon(arg: string): void;
+ dot(this: void, arg: string): void;
+}
+
+const c = new Class();
+c.colon("foo");
+c.dot("foo");
+```
+
+```lua
+local c = __TS__New(Class)
+c:colon("foo")
+c.dot("foo")
+```
+
+
+
+Common Lua libraries use callback functions that don't have a `self` parameter so make sure this is reflected in their declaration.
+
+**Example**
+
+
+
+
+```typescript
+type Callback = (
+ this: void,
+ arg: string
+) => void;
+
+declare function useCallback(
+ this: void,
+ callback: Callback
+): void;
+
+useCallback(arg => {
+ console.log(arg);
+});
+```
+
+```lua
+useCallback(function(arg)
+ print(arg)
+end)
+```
+
+
+
+### `@noSelf`
+
+If you wish to specify that all functions in a class, interface or namespace should not have a context parameter, you can use the [`@noSelf`](./advanced/compiler-annotations.md#noself) annotation.
+
+**Example**
+
+
+
+```typescript
+/** @noSelf **/
+declare namespace Namespace {
+ function foo(arg: string): void;
+}
+
+Namespace.foo("foo");
+```
+
+```lua
+Namespace.foo("foo")
+```
+
+
+
+You can override `@noSelf` on a per-function basis by specifying a `this` parameter.
+
+**Example**
+
+
+
+```typescript
+/** @noSelf **/
+declare namespace Namespace {
+ function foo(this: any, arg: string): void;
+}
+
+Namespace.foo("foo");
+```
+
+```lua
+Namespace:foo("foo")
+```
+
+
+
+### `@noSelfInFile`
+
+If you want to specify that all functions in a file should have no context, you can use [`@noSelfInFile`](./advanced/compiler-annotations.md#noselfinfile) at the top of the file.
+
+For more information on [`@noSelf`](./advanced/compiler-annotations.md#noself) and [`@noSelfInFile`](./advanced/compiler-annotations.md#noselfinfile), please refer to [Compiler Annotations](./advanced/compiler-annotations).
+
+### `noImplicitSelf`
+
+Use this option if you do not want implemented functions to have a self parameter.
+
+Ambient functions (functions described, not implemented) as well as classes and interfaces ignore this option.
+
+:::note
+Use this with `strict` or `noImplicitThis` to ensure you don't use an "implicit this" type in your code.
+:::
+
+_When enabled, if `this` has a type other than an implicit `any`, a `self` parameter will be added for its containing function._
+
+```json title=tsconfig.json
+{
+ "tstl": {
+ "noImplicitSelf": true
+ }
+}
+```
+
+
+
+```typescript
+function f() {}
+function f2(this: any) {}
+const a = () => {};
+class C {
+ method() {}
+}
+```
+
+```lua
+function f() end
+function f2(self) end
+local a = function() end
+
+local C = __TS__Class()
+function C:method(self) end -- still has self
+```
+
+
+
+## Assignment Errors
+
+See the two types below.
+
+```typescript
+type NoContext = (this: void) => void;
+type UseContext = () => void;
+```
+
+TypeScript sees `NoContext` to be assignable to `UseContext`.
+
+TypeScriptToLua does not.
+
+**Example**
+
+```ts
+declare function useCallback(cb: (this: void, arg: string) => void);
+// cb's type: (this: void, arg: string) => void
+
+function callback(arg: string) {}
+// callback's type: (arg: string) => void (implicit any)
+
+useCallback(callback);
+```
+
+> :x: **Error:** Unable to convert function with a 'this' parameter to function with no 'this'. To fix, wrap in an arrow function, or declare with 'this: void'.
+
+This throws an error because `callback's type` is not assignable to `cb's type` since the latter has an implicit any type which changes how the function should be called.
+
+To fix this, an arrow function can be used.
+
+**Example**
+
+
+
+```typescript
+useCallback((arg) => callback(arg));
+// argument type: (this: void, arg: string) => void
+```
+
+```lua
+useCallback(function(arg)
+ return callback(nil, arg)
+end)
+```
+
+
+
+TypeScript says the arrow function has no context due to the parameter's signature making TypeScriptToLua accept the parameter.
+
+### Overloads
+
+A similar error occurs if a function is overloaded and the call signature differs between how to use context:
+
+```ts
+declare function useCallback(f: () => {}): void;
+
+declare function callback(this: void, s: string, n: number): void;
+declare function callback(s: string);
+
+useCallback(callback);
+```
+
+> :x: **Error:** Unsupported assignment of function with different overloaded types for 'this'. Overloads should all have the same type for 'this'.
+
+It's best practice to avoid overloads with different context types.
diff --git a/sidebars.json b/sidebars.json
index 4db4962d..6c6869dc 100644
--- a/sidebars.json
+++ b/sidebars.json
@@ -3,15 +3,12 @@
"getting-started",
"configuration",
"caveats",
+ "the-self-parameter",
"editor-support",
{
"type": "category",
"label": "Advanced",
- "items": [
- "advanced/writing-declarations",
- "advanced/compiler-annotations",
- "advanced/functions-and-the-self-parameter"
- ]
+ "items": ["advanced/writing-declarations", "advanced/compiler-annotations"]
},
{
"type": "category",