টাইপস্ক্রিপ্টে কি `কীফোর অনুরূপ কোনও` মানফল` রয়েছে?


119

ইনপুট হিসাবে এখনও একটি কী এবং মান দেওয়া একটি মানকে আমি কোনও অবজেক্টের সম্পত্তি নির্ধারণ করতে সক্ষম হতে চাই তবে এখনও মানটির ধরণটি নির্ধারণ করতে সক্ষম হতে চাই। এটি ব্যাখ্যা করা কিছুটা কঠিন তাই এই কোডটি সমস্যাটি প্রকাশ করতে পারে:

type JWT = { id: string, token: string, expire: Date };
const obj: JWT = { id: 'abc123', token: 'tk01', expire: new Date(2018, 2, 14) };

function print(key: keyof JWT) {
    switch (key) {
        case 'id':
        case 'token':
            console.log(obj[key].toUpperCase());
            break;
        case 'expire':
            console.log(obj[key].toISOString());
            break;
    }
}

function onChange(key: keyof JWT, value: any) {
    switch (key) {
        case 'id':
        case 'token':
            obj[key] = value + ' (assigned)';
            break;
        case 'expire':
            obj[key] = value;
            break;
    }
}

print('id');
print('expire');
onChange('id', 'def456');
onChange('expire', new Date(2018, 3, 14));
print('id');
print('expire');

onChange('expire', 1337); // should fail here at compile time
print('expire'); // actually fails here at run time

আমি পরিবর্তন চেষ্টা value: anyকরতেvalue: valueof JWT কিন্তু যে কাজ করে নি।

আদর্শভাবে, onChange('expire', 1337)কারণ ব্যর্থ হবে1337 একটি তারিখ টাইপ নয়।

value: anyপ্রদত্ত কীটির মান হতে কীভাবে আমি পরিবর্তন করতে পারি ?

উত্তর:


221

আপডেট: দেখে মনে হচ্ছে প্রশ্নের শিরোনামটি সমস্ত সম্ভাব্য সম্পত্তি মানের ধরণের সংঘের সন্ধানকারী লোকদের আকর্ষণ করে, উপায় অনুসারে keyofআপনি সমস্ত সম্ভাব্য সম্পত্তি কী প্রকারের মিলন দেয়। আসুন প্রথমে সেই লোকগুলিকে সহায়তা করি। আপনি যেমন কী হিসাবে অনুসন্ধানেরValueOf ধরণগুলি keyofব্যবহার করে এর সাথে সাদৃশ্য তৈরি করতে পারেন:keyof T

type ValueOf<T> = T[keyof T];

যা আপনাকে দেয়

type Foo = { a: string, b: number };
type ValueOfFoo = ValueOf<Foo>; // string | number

যেমনটি বলা হয়েছে প্রশ্নের জন্য, আপনি স্বতন্ত্র কীগুলি ব্যবহার করতে পারেন, তার চেয়ে সংকীর্ণ, আপনার পছন্দসই keyof Tমানের মূল্যটি বের করতে:

type sameAsString = Foo['a']; // lookup a in Foo
type sameAsNumber = Foo['b']; // lookup b in Foo

কী / মান জুটি কোনও ফাংশনে সঠিকভাবে "মিলছে" তা নিশ্চিত করতে আপনার জেনেরিকগুলি পাশাপাশি লুকিংয়ের ধরণগুলি ব্যবহার করা উচিত :

declare function onChange<K extends keyof JWT>(key: K, value: JWT[K]): void; 
onChange('id', 'def456'); // okay
onChange('expire', new Date(2018, 3, 14)); // okay
onChange('expire', 1337); // error. 1337 not assignable to Date

ধারণাটি হ'ল keyপ্যারামিটারটি কম্পাইলারটিকে জেনেরিক Kপ্যারামিটার অনুমান করতে দেয় । তারপরে এটির প্রয়োজন valueমেলে JWT[K], আপনার প্রয়োজনীয় ধরণের লুকিং।

আশা করি এইটি কাজ করবে; শুভকামনা!


আমি tupleমানগুলি থেকে একটি তৈরি করতে চাই । এটা করার কোন সুযোগ আছে কি?
— মরতেজা তৌরানী

এটি একটি সম্পর্কিত সম্পর্কযুক্ত প্রশ্নের মতো মনে হচ্ছে তাই আপনার সম্ভবত এটি অন্য কোথাও জিজ্ঞাসা করা উচিত, একটি ন্যূনতম প্রজননযোগ্য উদাহরণ সহ যাতে লোকেরা আপনার ব্যবহারের বিষয়টি বোঝার বিষয়ে নিশ্চিত হন। শুভকামনা।
— jcalz

1
ফাংশনের সদস্যদের সাথে স্ট্রিং-ভ্যালু এনাম ব্যবহার করে কোনও সমস্যায় পড়ে। এটি ভালভাবে পরিচালনা করতে, আপনি ব্যবহার করতে পারেন type StringValueOf<T> = T[keyof T] & string;। স্ট্রিং এনামগুলিতে আমি যে সেরা
— দস্তাগুলি পেয়েছি তা হ'ল টাইপস্ক্রিপ্ট

41

কেউ যদি এখনও valueofকোনও উদ্দেশ্যে বাস্তবায়নের সন্ধান করে তবে এটিই আমি নিয়ে এসেছি:

type valueof<T> = T[keyof T]

ব্যবহার:

type actions = {
  a: {
    type: 'Reset'
    data: number
  }
  b: {
    type: 'Apply'
    data: string
  }
}
type actionValues = valueof<actions>

প্রত্যাশিত হিসাবে কাজ করে :) সমস্ত সম্ভাব্য ধরণের একটি ইউনিয়ন প্রদান করে


2
এটা সুন্দর. এটি আমার অন্যান্য সমস্যাটি প্রায় সমাধান করে , তবে স্যুইচটি মোটেও টাইপটিকে সঙ্কীর্ণ বলে মনে হচ্ছে না।
— স্টাইফেল

আমি tupleমানগুলি থেকে একটি তৈরি করতে চাই । এটা করার কোন সুযোগ আছে কি?
— মরতেজা তৌরানী

12

ইউনিটের ধরণের অবজেক্টটি বের করার আরও একটি উপায় রয়েছে:

  const myObj = { a: 1, b: 'some_string' } as const;
  type values = typeof myObj[keyof typeof myObj];

ফলাফল: 1 | "some_string"


এই constজিনিসটি খুব মূল্যবান, টাইপস্ক্রিপ্ট আসলে মানগুলি নিজেরাই সরবরাহ করবে এবং সদৃশগুলি সরিয়ে দেবে; এটি অভিধানের জন্য খুব ভাল।
— নওমর

ঠিক আমি খুঁজছেন ছিল কি !
— মাভ্রিক আরএমএক্স

2

সমস্যাগুলি পুরোপুরি সমাধান করার জন্য বিদ্যমান উত্তরগুলি ধন্যবাদ। আপনি যদি এই সাধারণটি আমদানি করতে পছন্দ করেন তবে কেবল একটি lib যোগ করতে চেয়েছিলেন এই উপযোগের ধরণটি অন্তর্ভুক্ত করেছে।

https://github.com/piotrwitek/utility-types#valuestypet

import { ValuesType } from 'utility-types';

type Props = { name: string; age: number; visible: boolean };
// Expect: string | number | boolean
type PropsValues = ValuesType<Props>;

2

এটা চেষ্টা কর:

type ValueOf<T> = T extends any[] ? T[number] : T[keyof T]

এটি একটি অ্যারে বা একটি সরল বস্তুর উপর কাজ করে।

// type TEST1 = boolean | 42 | "heyhey"
type TEST1 = ValueOf<{ foo: 42, sort: 'heyhey', bool: boolean }>
// type TEST2 = 1 | 4 | 9 | "zzz..."
type TEST2 = ValueOf<[1, 4, 9, 'zzz...']>

0

এক রৈখিক:

type ValueTypesOfPropFromMyCoolType = MyCoolType[keyof MyCoolType];

জেনেরিক পদ্ধতির উদাহরণ:

declare function doStuff<V extends MyCoolType[keyof MyCoolType]>(propertyName: keyof MyCoolType, value: V) => void;
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.