#Keyof Object + any string

1 messages · Page 1 of 1 (latest)

solemn patrolBOT
#

@full remnant Here's a shortened URL of your playground link! You can remove the full link from your message.

mochoman#0

Preview:```ts
const obj = {
firstName: "first",
lastName: "last",
}

type Obj = typeof obj

type KeysAndString<T> = {
key: (string & {}) | keyof T
}

const anotherObj: KeysAndString<Obj>[] = [
{
key: "firstName", // autocomplete OK
},
{
key: "foo", // allows other non-keys
...```

abstract raft
#

this is a bit verbose, but i think it does what you want:

solemn patrolBOT
#
mkantor#0

Preview:```ts
const obj = {
firstName: 'first',
lastName: 'last'
}

type Obj = typeof obj;

type KeysAndString<T> = {
key: (string & {}) | keyof T
};

const anotherObj = [{
key: 'firstName' // autocomplete OK
},
{
key: 'foo' // allows other non-keys
}] as const satisfies readonly KeysAndString<Obj>[];
...```

abstract raft
#

a key point is the usage of const anotherObj = ... satisfies X instead of const anotherObj: X = .... the latter throws away any information beyond what X represents, so there's no way later on to figure out that 'foo' was given as a key while 'name' wasn't

alpine marsh
#

What about?

type Slots<T extends readonly { key: string }[]> = {
  [K in T[number]['key'] as `item-${K}`]: Obj
}
abstract raft
#

ah yeah much better. i tried something like that initially but at that point i was under the mistaken impression that they wanted the values to be specific to the array element instead of always Obj

full remnant
#

Thank you

full remnant
#

So this works however because it's hidden inside a reusable function, I'm losing some of the types - here is something much closer to the actual use case https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgJQKYDMA0cDGFwCuMqAJtlBnAL5zpT5wBEAbgaowNwCwAUL6gA9IsODACeYVHADCEADYEQAOwAiGADwAVAHxwAvIl5w4AehNxUAZznAlMALQlglgIYAjOantLBDmz7gAAXFJSxwoYDAHK38YEzcXJXsQqyM4AGtUMQAuOAAKSxgIpQBzOAAyRCoASjgAHwysiHQ4TW4eYxhgGE9cwuKS9qp23hTW908AeSjgCCVLLV0DBDSSFxgXXLR0LQBtAF16uAIlEgxbUm124zwFZUtc2TvVDR0DoZGeMYAJVBczqCLfSGDpwYAkR7yRQvHZvRiZMSMfbXRo5GRQ5RqWHaXbwrJIlFdHqoPpFWyDNK3ADKYESuSUijcqCgH14owkUie0KByzSCMhzyxi1xCIJlPkNLpcAZICZLLSAAs-gDcr9-szFqy+F8OSgIAB3Hkgm6oORyB4yU1yYXI3jDNk6ySWs1Glag5guBQk45KdJKA1KFG3aEC7k6LX8ITQeDoE44LpzY6WVAAQU0E1QizyEBmcwt6Y8qGmCfmi1qbpuefgwfuwLwhGIJDyeVqem0aWMOZLlgAdDX5j2QC4wM3+63dBXjFOKDACFAlMap0v+bgMUoewjMB2l6u5JKlLkAIxb0E7uBK9VQXKTs-GcG5fsbrIn29TlePzfbs9E3q76E9n9UBfV9d33I9gLPKgIKne1T2oao0mqT5K3meB6H1Sw63wMAiFIZtx23bNcwHNYNh7D0vTgAB+Ki4AOapB2HZtulQEBx0XJc8FQ3ArUwgx+17Ci2EYkc8jHfQJy-KcuMKVEsOeHsLwBJ8xDgFxMIRZpRA5LSWJAFEzxnOcFxvW8hO9PTdgRQ4aJ9M50AuMgpM4tdoKXWDIKQh1DNQWd5w4nccF4tzqAM+DEOQ1duKU5k+NXBs8JbCS-3ucjPWEodRPEtsUvXGKoGqLztRQ2SETi+scMbfDkoEtKvRE0c13Yj8skKyKjP80z8ssaD0J67cyuA2CqAdQRhHgMYqWZZhmQLTxXUVZVYq2DQ1QBG0rjSPqVp2ZADQ2iMeDG6NtKdObMx0YE0D8pRNA5dQUi0ghkzTDNFk27UxgABRcWBgBwSJEhgAB1boFTQOR1lmeZgUnByoEKAA5FwQG9fpyRRSGkZRtGyVKIYHRk6s1wtLlMQ0H6-oB2k7FBmBwdNKG8xxQ4DF2NIkEA3JGERlQAEkqTgRHGWZRhsBXRhTmcYXZVF6hgNMrmmAAMWABH4GR1GxYGrJufh7GtewMw1KICAKs8Yhz2ZVA0igjntyVxgABl1I1nHtbgiWsZgTX2CGhWHe6X9GFkaAnCUdZoA95ddaYPAw9sSOoDF0xzH9E2YDN7CLakNwiFEBVnDBTDPTkA1SFtgO4Mdl3iFk6QlRwdJbGjt9Y8YSG65gBvUCblv-ft6ug+9Rh0xKSxW+MCWNnH1u7dBRXh+5yfUWXgeeFtbUibgUiXGBCgdkprpqaBumGc76HLAObQ8nowmq1EDNgWe1NzvUI--sB2mwYhpn5hvycu9gICRPDUT4ZwcCQwoLQOMJY4BDkyFSMuMAFg6BbNeNIuwADSYIFwAAM9L2AACQIDfm8AA5GVch+xdjkPMtQ3YMo5T7CoHg-YuQ2h2nvtxawEAUHAgQagJBfCFgfxPt-emv9uw3yKrwXhKDaGEP1j7HG1CezKN9hwVOcBJhYLkcgq+5DCHxygOHJOaiNE4y0cbXRcB7DSj4WpOSWkxFf3gHneARd7KOVwblSw+iRGKOICAbwqj9jqLVgbVA1jzAnG8T4Egdi4CWAVBAAgchEnMnoEAA

solemn patrolBOT
#

@full remnant Here's a shortened URL of your playground link! You can remove the full link from your message.

mochoman#0

Preview:```ts
import {Ref, computed, ref} from "vue"

export type ColumnDef<T> = {
// eslint-disable-next-line @typescript-eslint/ban-types
key: (string & {}) | keyof T
title: string
}

type TableOptions<T> = {
data: Ref<T[] | undefined>
columns: ColumnDef<T>[
...```