8000 Suggestion: polymorphic object and tuple member type references through literal types · Issue #7730 · microsoft/TypeScript · GitHub
[go: up one dir, main page]

Skip to content
Suggestion: polymorphic object and tuple member type references through literal types #7730
Closed
@malibuzios

Description

@malibuzios

(This seems to have some things in common with #6080 and is strongly related to #1295 as it can be used to provide an alternative solution to it but l opened this separately since I did not feel it was appropriate to continue discussing it there and wanted to approach it in a more generalized way)

This would provide improved type safety for cases where an interface property is referenced through a string having a value that's known at compile time:

type MyType = { "ABC": number };
let x: MyType = { ABC: 42 };

const propName = "ABC"; // 'propName' received the literal type "ABC" (not string)
let y = x[propName]; // 'y' received the type MyType["ABC"] which resolved to 'number'

And with support for generic types added, this could work similarly, but resolve to an intermediate type of the form T[S] where T is an object type and S is a string literal type:

function func<T extends object>() {
    let x: T;
    const propName = "ABC"; // 'propName' received the literal type "ABC"
    let y = x[propName]; // 'y' would receive the type T["ABC"]
}

This could combine with readonly function parameters to provide an alternative solution for #1295 (which was actually where the idea was initially proposed):

function getProperty<T extends object, S extends string>(obj: T, readonly propName: S): T[S] {
    return obj[propName];
}

// Here T resolves to { ABC: number }, S resolves to the literal type "ABC", 
// and T[S] resolves to number
let x = getProperty({ABC: 42}, "ABC"); // Type of 'x' is number

// Here T resolves to { ABC: number }, S resolves to the literal type "CBA" 
// and T[S] resolves to any
let x = getProperty({ABC: 42}, "CBA"); // Type of 'x' is any

// Here T resolves to { ABC: number }, S resolves to string
// and T[S] resolves to any
let x = getProperty({ABC: 42}, getRandomString()); // Type of 'x' is any

This may similarly extend to numeric literal types, for tuples:

type MyTupleType = [number, string, boolean];
let x: MyTupleType;
const index = 1; // 'index' received the literal type 1;

let y = x[index]; // 'y' received the type MyTupleType[1] which resolved to 'string'

And work with generic tuples as well:

function getTupleElement<T extends Array<any>, N extends number>(tuple: T, readonly index: N): T[N] {
    return tuple[index];
}

Same can be done with symbol literal types (haven't thought about that much though):

function getSymbolProperty<T extends object, S extends symbol>(obj: T, readonly sym: S): T[S] {
    return obj[sym];
}

Metadata

Metadata

Assignees

Labels

FixedA PR has been merged for this issueSuggestionAn idea for TypeScript

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions

    0